views:

317

answers:

3

I have a set of folders that has a depth of at least 4 or 5 levels. I'm looking to recurse through the directory tree as deep as it goes, and iterate over every file. I've gotten the code to go down into the first sets of subdirectories, but no deeper, and I'm not sure why. Any ideas?

$count = 0;
$dir = "/Applications/MAMP/htdocs/site.com";
function recurseDirs($main, $count){
    $dir = "/Applications/MAMP/htdocs/site.com";
    $dirHandle = opendir($main);
    echo "here";
    while($file = readdir($dirHandle)){
        if(is_dir($file) && $file != '.' && $file != '..'){
            echo "isdir";
            recurseDirs($file);
        }
        else{
            $count++;
            echo "$count: filename: $file in $dir/$main \n<br />";
        }
    }
}
recurseDirs($dir, $count);
+5  A: 

Check out the new RecursiveDirectoryIterator.

It's still far from perfect as you can't order the search results and other things, but to simply get a list of files, it's fine.

There are simple examples to get you started in the manual like this one:

<?php

$path = realpath('/etc');

$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), 
RecursiveIteratorIterator::SELF_FIRST);

foreach($objects as $name => $object){
    echo "$name\n";
}

?>
Pekka
Just one remark: an iterator does what it's name implies. It iterates over an iterable source. That's no different from iterating over an array. If you'd want the results sorted, then you'd have to do this in the foreach loop or write/use a function to do this for you.
Gordon
@Gordon true. But being able to get the results sorted and/or filtered straight away is a feature I would expect from a recursive directory iterator nevertheless - I understand that that may not be in the spririt of the SPL, but still. As it is, there is again the need to come up with dozens of lines of code (with hundreds of snippets on the net, all varying in quality) to perform a pretty standard task, where other languages offer ready-made functions. That pisses me off a bit sometimes.
Pekka
@Pekka Since everything can be an Iterable now, it is impossible to come up with a generic sort. How should it know I want my Person objects to be sorted by $firstName but my Files by MTime? You *have* to script that. If you want to query objects by generic expressions, have a look at PHPLinq.
Gordon
@Gordon true, and not the job of an iterator. I guess what I'm trying to say is, I would like to see a PHP standard library for file operations that is better and more powerful than what is available right now.
Pekka
@Pekka have a look at http://github.com/theseer/DirectoryScanner or http://github.com/sebastianbergmann/php-file-iterator then. Also, I am currently in the process of writing a FilterIterator that allows for filtering based on File attributes.
Gordon
@Gordon thanks for the links, they look exactly like what I'm looking for! We really, really need a central repository for high-quality PHP code. http://stackoverflow.com/questions/2345412/quality-php-code-snippet-repositories
Pekka
+1  A: 

There is an error in the call

recurseDirs($file);

and in

is_dir($file)

you have to give the full path:

recurseDirs($main . '/' .$file, $count);

and

is_dir($main . '/' .$file)

However, like other anwerers, I suggest to use RecursiveDirectoryIteretor.

Nicolò Martini
A: 

The call to is_dir and recurseDirs is not fully correct. Also your counting didn't work correctly. This works for me:

$dir = "/usr/";
function recurseDirs($main, $count=0){
    $dirHandle = opendir($main);
    while($file = readdir($dirHandle)){
        if(is_dir($main.$file."/") && $file != '.' && $file != '..'){
            echo "Directory {$file}: <br />";
            $count = recurseDirs($main.$file."/",$count); // Correct call and fixed counting
        }
        else{
            $count++;
            echo "$count: filename: $file in $main \n<br />";
        }
    }
    return $count;
}
$number_of_files = recurseDirs($dir);

Notice the changed calls to the function above and the new return value of the function.

svens