0

I was looking at RecursiveDirectoryIterator and glob to say

"return me a list of files (in an array) based on the extension (for example) .less. Oh and look in all child, grandchild and so on and so forth, excluding . and .. until you find all files matching."

But I am not sure the best approach to create a recursive function that keeps going well beyond the grand child.

What I have is a mess, its worked for two years - but now I need to refactor and change it up:

public function get_directory_of_files($path, $filename, $extension) {
        if (!is_dir($path)) {
            throw new AisisCore_FileHandling_FileException("Could not find said path: " . $path);
        }

        if (file_exists($filename)) {
            $handler = opendir($path);
            while ($file = readdir($handler)) {
                if ($file != "." && $file != "..") {
                    $this->package_files [] = $file;
                    $count = count($this->package_files);
                    for ($i = 0; $i < $count; $i++) {
                        if (substr(strrchr($this->package_files [$i], '.'), 1) == $extension) {
                            if ($this->package_files [$i] == $filename) {
                                $this->files_got_back = $this->package_files [$i];
                            }
                        }
                    }
                }
            }
        }

        return $this->_files_got_back;
    }

This requires a file name to be passed in and thats not really my thing to do any more. So how can I re-write this function to do the above "pseudo code"

  • Have you seen this question http://stackoverflow.com/questions/12109042/php-get-file-listing-including-sub-directories? – elclanrs Feb 03 '14 at 03:35

2 Answers2

0

Take a look at this code:

<?php

class ex{

    private function get_files_array($path,$ext, &$results){ //&to ensure it's a reference... but in php obj are passed by ref.

        if (!is_dir($path)) {
            //throw new AisisCore_FileHandling_FileException("Could not find said path: " . $path);
        }

        if ($dir = opendir($path)) {
            $extLength = strlen($ext);

            while (false !== ($file = readdir($dir))) {
                if ($file != '.' && $file != '..'){
                    if (is_file($path.'/'.$file) && substr($file,-$extLength) == $ext){
                        $results[] = $path . '/' . $file; //it's a file and the correct extension
                    }
                    elseif (is_dir($path . '/'. $file)){ 
                        $this->get_files_array($path.'/'.$file, $ext, $results); //it's a dir
                    }               
                }
            }

        }else{
            //unable to open dir
        }
    }

    public function get_files_deep($path,$ext){
        $results = array();
        $this->get_files_array($path,$ext,$results);
        return $results;
    }

}

    $ex = new ex();

    var_dump($ex->get_files_deep('_some_path','.less'));

?>

It will retrieve all the files with the matching extension in the path and it's sub directories.

I hope it's what you need.

Ignacio
  • 11
  • 1
  • 2
  • note: you may lowercase the extension, but if you do so and you are in linux, you may endup getting wrong results – Ignacio Feb 03 '14 at 04:04
  • It's probably better to convert all ext to upper case before comparison. – thor Feb 03 '14 at 04:24
  • as I said before... if you are under windows, the case is not important so, it'll be good to lowercase the extension, but if you are under Linux or Mac the file names are case sensitive... so for instance .jpg is not the same as .JPG – Ignacio Feb 04 '14 at 19:59
0

This function recursively finds files with a matching ending string

function getDirectoryContents($directory, $extension)
{
    $extension = strtolower($extension);
    $files = array();
    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));

    while($it->valid()) 
    {
        if (!$it->isDot() && endsWith(strtolower($it->key()), $extension))
        {
            array_push($files, $it->key());
        }
        $it->next();
    }
    return $files;
}
function endsWith($haystack, $needle)
{
    return $needle === "" || substr($haystack, -strlen($needle)) === $needle;
}

Used like so print_r(getDirectoryContents('folder/', '.php'));

It converts the extension to lowercase to compare against

duindain
  • 525
  • 3
  • 12