tags:

views:

577

answers:

3

I'm using the following code to loop through a directory to print out the names of the files. However, not all of the files are displayed. I have tried using clearstatcache with no effect.

 $str = '';
 $ignore = array('.', '..');

 $dh = @opendir( $path );
 if ($dh === FALSE)
 {
  // error
 }

 $file = readdir( $dh );
 while( $file !== FALSE )
 {
  if (in_array($file, $ignore, TRUE)) { break; }
  $str .= $file."\n";
  $file = readdir( $dh );
 }

Here's the contents of the directory right now:

root.auth  test1.auth  test2.auth  test3.auth  test5.auth

However, test5.auth does not appear. If I rename it to test4.auth it does not appear. If I rename it to test6.auth it does appear. This is reliable behaviour - I can rename it several times and it still won't show up unless I rename it to test6.auth.

What on earth could be happening?

I'm running Arch Linux (kernel 2.6.26-ARCH) with PHP Version 5.2.6 and Apache/2.2.9 with Suhosin-Patch. My filesystem is ext3 and I'm running fam 2.6.10.

+1  A: 

Your break keywords messes up your code:
Your loop very likely first encounters the '.' directory and than breaks out of your while loop.

try replacing it with a continue and you should be fine.

Jacco
D'oh! Man, do I feel stupid now. Thanks!
HoboBen
Just fresh pair of eyes.
Jacco
+1  A: 
if (in_array($file, $ignore, TRUE)) { break; }

Surely that should be continue not break?

Greg
+3  A: 

Surely continue won't work either, because you will miss out the line that reads the next file from the dir. ( $file = readdir( $dh ); )

It would be better to get rid of the first $file = readdir( $dh ); and then do

while (false !== ($file = readdir($dh))) {
    if (in_array($file, $ignore, TRUE)) { continue; }
    $str .= $file."\n";
}
Tom Haigh
Well spotted - can't believe we all missed that one! This is also the recommend approach from the php manual: http://uk3.php.net/manual/en/function.readdir.php. +1 (and -1 the accepted answer)
Bobby Jack
Yep - I did catch that (couldn't remember the (false !== ($file = readdir($dh))) syntax off the top of my head when I pulled together the script) but that's absolutely right.
HoboBen