3

I'm trying to use the GlobIterator class.

I am using the same PATTERN as in the glob function, but the GlobIterator produces an empty array.

Example:

$glob = glob('./*');
print_r($glob);

will give me an array of all files in the current directory.

But when I do

$glob = new GlobIterator('./*');
print_r(iterator_to_array($glob));

The result is just Array() with no items in the array.

Can someone tell me why this happens?

I have tested this on Windows 8 / Apache 2 / PHP 5.3.

Apparently, this works from CLI and also on Linux.

Maybe it's a bug with the Apache SAPI on Windows?

Gordon
  • 312,688
  • 75
  • 539
  • 559
Jasper
  • 2,314
  • 3
  • 26
  • 33
  • Try to use `__DIR__ . '/*'` instead of `'./*'`. If that still fails, it might have to do with https://bugs.php.net/bug.php?id=55701. – Gordon May 10 '13 at 13:29

1 Answers1

3

Introduction

According to the PHP Documentation, glob and GlobIterator initial parameter is totally different. Its not clear why this is so but its was clearly stated.

glob

 array [glob][3] ( string $pattern [, int $flags = 0 ] )
                              ^
                              |--- Expects pattern

GlobIterator

public [GlobIterator::__construct][5] ( string $path [, int $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO ] )
                                                 ^
                                                 |--- Expects Path

The Solution

Always use full path. Have see this error a couple of times but if you use full path you can be assure they would both return the same file list

Example without full path

$path = "./test";
$glob1 = glob($path . '/*');
print_r($glob1);

$glob2 = new GlobIterator($path . '/*');
print_r(iterator_to_array($glob2));

Output

Array
(
    [0] => ./test/fake.png
    [1] => ./test/php-logo-virus.jpg
    [2] => ./test/save
    [3] => ./test/test.png
)
Array
(
)

Example with Full Path

$path = __DIR__ ."/test";
$glob1 = glob($path . '/*');
print_r($glob1);

$glob2 = new GlobIterator($path . '/*');
print_r(iterator_to_array($glob2));

Output

Array
(
    [0] => C:\lab\stackoverflow/test/fake.png
    [1] => C:\lab\stackoverflow/test/php-logo-virus.jpg
    [2] => C:\lab\stackoverflow/test/save
    [3] => C:\lab\stackoverflow/test/test.png
)
Array
(
    [C:\lab\stackoverflow/test\fake.png] => SplFileInfo Object
        (
            [pathName:SplFileInfo:private] => C:\lab\stackoverflow/test\fake.png
            [fileName:SplFileInfo:private] => fake.png
        )

    [C:\lab\stackoverflow/test\php-logo-virus.jpg] => SplFileInfo Object
        (
            [pathName:SplFileInfo:private] => C:\lab\stackoverflow/test\php-logo-virus.jpg
            [fileName:SplFileInfo:private] => php-logo-virus.jpg
        )

    [C:\lab\stackoverflow/test\save] => SplFileInfo Object
        (
            [pathName:SplFileInfo:private] => C:\lab\stackoverflow/test\save
            [fileName:SplFileInfo:private] => save
        )

    [C:\lab\stackoverflow/test\test.png] => SplFileInfo Object
        (
            [pathName:SplFileInfo:private] => C:\lab\stackoverflow/test\test.png
            [fileName:SplFileInfo:private] => test.png
        )

)

Output Different Format

As you can see $glob1 !== $glob2 not because the files are not present but because glob would return a array with string path of files while GlobIterator would return SplFileInfo which has its on advantages.

To get pure array list from GlobIterator :

print_r(array_values(array_map("strval",iterator_to_array($glob2))));

Conclusion

Yes your code would work on any platform so far you do Unit Testing and maintain consistency. I don't need to start telling the advantages of GlobIterator or Iterator or glob but be rest assured when used properly would return same result

Baba
  • 94,024
  • 28
  • 166
  • 217
  • You can also make use of the `CURRENT_AS_PATHNAME` flag if you want to have strings instead of `SplFileInfo`s. – hakre May 23 '13 at 23:14