Get all paths in a directory using PHP

Published on

I hate recursion. Writing the code equivalent of an M. C. Escher woodcut gives me a headache.

One activity that typically demands recursion is scraping a directory and its subdirectories for file paths. Luckily, I found this example on php.net and managed to improve it a bit for my own needs.

The first (and only required) argument is the server path you’d like to scan. The second argument defaults to true and determines whether directories will be included in the result. The third argument allows you to specify a file extension to filter results against. For example, if you only want to return paths to JavaScript files, the value would be 'js'.

function dir_tree( $dir, $include_dirs=true, $only_ext=null ) {
    $paths = array();
    $stack[] = $dir;
    while ( count( $stack ) ) {
        $this_dir = array_pop( $stack );
        foreach( scandir( $this_dir ) as $file ) {
            if ( $file !== '.' && $file !== '..' ) {
                $path = $this_dir . '/' . $file;
                if ( is_file( $path ) ) {
                    if ( $only_ext && substr( strrchr( $file, '.' ), 1 ) !== $only_ext ) {
                        continue;
                    }
                    $paths[] = $path;
                } elseif ( is_dir( $path ) ) {
                    if ( $include_dirs ) {
                        $paths[] = $path;
                    }
                    $stack[] = $path;
                }
            }
        }
    }
    return $paths;
}

This function returns an array like this:

array(
    '/my/server/path',
    '/my/server/path/file.txt',
    '/my/server/path/image.jpg',
    '/my/server/path/subdir',
    '/my/server/path/subdir/style.css'
)

If I set $include_dirs to false:

array(
    '/my/server/path/file.txt',
    '/my/server/path/image.jpg',
    '/my/server/path/subdir/style.css'
)

If I set $only_ext to 'css':

array(
    '/my/server/path/subdir/style.css'
)

This is the first deep directory scanning function I’ve found comprehensible, but I’m sure there’s room for improvement. Let me know if you find some useful tweaks.