Retrieving all directorie names (relative path)
Have you considered using SPLs RecursiveIteratorIterator and RecursiveDirectoryIterator? Like this:

$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this-&gt;directory), RecursiveIteratorIterator::CHILD_FIRST);
foreach($iterator as $path){
    if($path-&gt;isDir()){
        $cache = $this-&gt;GetInfoArray($path-&gt;__toString());
        isset($cache) ? $this-&gt;listing['directories'][] = $cache : "";
        unset($cache);
    } else {
        $this-&gt;listing['files'][] = $this-&gt;GetInfoArray($path-&gt;__toString());
    }
}


This will leave you with an array with two main nodes: files and directories. I wrote this for a PHP distributed test-and-build-on-commit system and it worked well. More info on the PHP SPL Iterators can be found here: http://www.php.net/manual/en/spl.iterators.php

By the way, the GetInfoArray is this: 

private function GetInfoArray($path){
    $d = new SplFileInfo($path);
    if($d-&gt;getBasename() == "." || $d-&gt;getBasename() == ".."){
        return;
    } else {
        return array(
           "pathname"    =&gt; $d-&gt;getPathname(),
           "access"      =&gt; $d-&gt;getATime(),
           "modified"    =&gt; $d-&gt;getMTime(),
           "permissions" =&gt; $d-&gt;getPerms(),
           "size"        =&gt; $d-&gt;getSize(),
           "type"        =&gt; $d-&gt;getType(),
           "path"        =&gt; $d-&gt;getPath(),
           "basename"    =&gt; $d-&gt;getBasename(),
           "filename"    =&gt; $d-&gt;getFilename()
        );
    }
}


In the end, you're left with something like this:

$this-&gt;listing['files']['smiles.jpg']['pathname'] = "/srv/www/smiles.jpg"
$this-&gt;listing['files']['smiles.jpg']['access'] = "1323546894"
$this-&gt;listing['files']['smiles.jpg']['modified'] = "2316546521"
$this-&gt;listing['files']['smiles.jpg']['permissions'] = "744"
$this-&gt;listing['files']['smiles.jpg']['size'] = "12Kb"
$this-&gt;listing['files']['smiles.jpg']['type'] = "jpg"
$this-&gt;listing['files']['smiles.jpg']['path'] = "/srv/www"
$this-&gt;listing['files']['smiles.jpg']['basename'] = "smiles"
$this-&gt;listing['files']['smiles.jpg']['filename'] = "smiles.jpg"


What the heck, heres the class itself:



# Done

class DirectoryReader{
    private $directory;
    private $listing;

    public function __construct($directory){
        try {
            $this-&gt;directory = $directory;
            $this-&gt;listing = array();
            $this-&gt;ListDir();
        } catch(UnexpectedValueException $e){
            die("Path cannot be opened.");
        } catch(RuntimeException $e){
            die("Path given is empty string.");
        }
    }

    public function GetListing(){
        return $this-&gt;listing;
    }

    private function ListDir(){
        $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this-&gt;directory), RecursiveIteratorIterator::CHILD_FIRST);
        foreach($iterator as $path){
            if($path-&gt;isDir()){
                $cache = $this-&gt;GetInfoArray($path-&gt;__toString());
                isset($cache) ? $this-&gt;listing['directories'][] = $cache : "";
                unset($cache);
            } else {
                $this-&gt;listing['files'][] = $this-&gt;GetInfoArray($path-&gt;__toString());
            }
        }
    }

    private function GetInfoArray($path){
        $d = new SplFileInfo($path);
        if($d-&gt;getBasename() == "." || $d-&gt;getBasename() == ".."){
            return;
        } else {
            return array(
               "pathname"    =&gt; $d-&gt;getPathname(),
               "access"      =&gt; $d-&gt;getATime(),
               "modified"    =&gt; $d-&gt;getMTime(),
               "permissions" =&gt; $d-&gt;getPerms(),
               "size"        =&gt; $d-&gt;getSize(),
               "type"        =&gt; $d-&gt;getType(),
               "path"        =&gt; $d-&gt;getPath(),
               "basename"    =&gt; $d-&gt;getBasename(),
               "filename"    =&gt; $d-&gt;getFilename()
            );
        }
    }
}


As a further note, you can also just call scandir($directory) and filter via is_dir() in a foreach.