I'm actually asking this myself for years now:
is it save to skip the first and second value of an array fetched by scandir
?
By now I'm iterating over an array fetched by scandir
(more or less) like this:
for ( $scan = scandir('path/to/dir/'), $i = 0, $c = count( $scan ); $i < $c; ++$i )
{
if ( $scan[ $i ][ 0 ] != '.' )
{
// $scan[ $i ] is file name or dir name
}
}
This works perfectly fine as well but seems to be redundant if $scan[ 0 ][ 0 ]
is always .
and $scan[ 1 ][ 0 ]
is always ..
.
So would it be save to skip the first and second value like this:
for ( $scan = scandir('path/to/dir/'), $i = 2/* starting with 2 instead of 0 */, $c = count( $scan ); $i < $c; ++$i )
{
// $scan[ $i ] is file name or dir name
}
When I var_dump
a scandir
I always get and got a structure like this:
var_dump( scandir('path/to/dir/') );
array(
0 => '.', // is this the case for each
1 => '..', // and every environment
2 => 'filename.ext',
[...]
)
But I'm mostly working in my own server environment and haven't seen too much different server environments. So can I be sure that in each and every environment (OS, PHP version, etc.) I will find a structure fetched by scandir
that will look similar like the one above?
No, you cannot safely assume that .
and ..
will be returned first.
By default, the results from scandir()
are returned in alphabetical order, as if the result had been passed to sort()
. However, there are characters that will sort above .
-- for instance, a file named !README
will be returned before .
.
If you want to skip these entries, check for them explicitly, e.g.
foreach (scandir("path/to/dir") as $file) {
if ($file === "." || $file === "..")
continue;
// do stuff with $file
}