How to recursively iterate through files in PHP?

后端 未结 7 1833
走了就别回头了
走了就别回头了 2021-02-12 16:47

I have set up a basic script that is posting an array of paths to find template files inside them; currently it\'s only searching two levels deep and I\'m having some troubles g

相关标签:
7条回答
  • 2021-02-12 17:07

    Here is working code which scans given directory $dir and all of its sub directories to any levels and return list of html files and folders containing them.

    <?php
    
    function find_all_files($dir)
    {
    
        if(!is_dir($dir)) return false;
    
        $pathinfo = '';
    
    
        $root = scandir($dir);
    
        foreach($root as $value)
        {
            if($value === '.' || $value === '..') {continue;}
    
    
    
    
            if(is_file("$dir/$value")) {
    
                $pathinfo = pathinfo($dir.'/'.$value);
    
                if($pathinfo['extension'] == 'html') {
                    $result[]="$dir/$value";
    
    
                }
    
                continue;
    
            }
    
            foreach(find_all_files("$dir/$value") as $value)
            {
    
                $result[]=$value;
    
            }
        }
    
        return $result;
    
    }
    
    //call function
    $res = find_all_files('physical path to folder'); 
    
    print_r($res);
    
    ?>
    
    0 讨论(0)
  • 2021-02-12 17:10

    Universal File search in folder, sub-folder :

    function dirToArray($dir,$file_name) {
       $result = array();
       $cdir = scandir($dir);
       foreach ($cdir as $key => $value)
       {
          if (!in_array($value,array(".","..")))
          {
             if (is_dir($dir . DIRECTORY_SEPARATOR . $value))
             {
                $result[$value] = dirToArray($dir . DIRECTORY_SEPARATOR . $value,$file_name);
             }
             else
             {
                if($value == $file_name){
                    $result[] = $value; 
                }
             }
          }
       }
       return $result;
    }
    
    define('ROOT', dirname(__FILE__));
    $file_name = 'template.html';
    $tree = dirToArray(ROOT,$file_name);
    echo "<pre>".print_r($tree,1)."</pre>";
    

    OUTPUT :

    Array
    (
        [components] => Array
            (
                [side] => Array
                    (
                        [second] => Array
                            (
                                [0] => template.html
                                [third] => Array
                                    (
                                        [0] => template.html
                                    )
    
                            )
    
                        [0] => template.html
                    )
    
                [0] => template.html
            )
    
        [0] => template.html
    )
    
    0 讨论(0)
  • 2021-02-12 17:13

    Alternative of my previous answer :

    $dir = 'components';
    function getFiles($dir, &$results = array(), $filename = 'template.html'){
        $files = scandir($dir);
        foreach($files as $key => $value){
            $path = realpath($dir.'/'.$value);
            if(!is_dir($path)) {
                if($value == $filename)         
                    $results[] = $path;         
            } else if($value != "." && $value != "..") {
                getFiles($path, $results);
            }
        }
        return $results;
    }
    echo '<pre>'.print_r(getFiles($dir), 1).'</pre>';
    

    OUTPUT :

    Array
    (
        [0] => /web/practise/php/others/test7/components/side/second/template.html
        [1] => /web/practise/php/others/test7/components/side/second/third/template.html
        [2] => /web/practise/php/others/test7/components/side/template.html
        [3] => /web/practise/php/others/test7/components/template.html
    )
    
    0 讨论(0)
  • 2021-02-12 17:19

    Another solution is using Finder component from Symfony. It's tested and proven code. Take a look at it here: http://symfony.com/doc/current/components/finder.html

    0 讨论(0)
  • 2021-02-12 17:21

    PHP has the perfect solution for you built in.

    Example

    // Construct the iterator
    $it = new RecursiveDirectoryIterator("/components");
    
    // Loop through files
    foreach(new RecursiveIteratorIterator($it) as $file) {
        if ($file->getExtension() == 'html') {
            echo $file;
        }
    }
    

    Resources

    • DirectoryIterator - Manual
    0 讨论(0)
  • 2021-02-12 17:23

    PHP 5 introduces iterators to iterate quickly through many elements.

    You can use RecursiveDirectoryIterator to iterate recursively through directories.

    You can use RecursiveIteratorIterator on the result to have a flatten view of the result.

    You can use RegexIterator on the result to filter based on a regular expression.

     $directory_iterator = new RecursiveDirectoryIterator('.');
     $iterator       = new RecursiveIteratorIterator($directory_iterator);
     $regex_iterator = new RegexIterator($iterator, '/\.php$/');
     $regex_iterator->setFlags(RegexIterator::USE_KEY);
     foreach ($regex_iterator as $file) {
        echo $file->getPathname() . PHP_EOL;
     }
    

    With iterators, there are lot of ways to do the same thing, you can also use a FilterIterator (see the example on the page)

    For instance, if you want to select the files modified this week, you can use the following:

      $directory_iterator = new RecursiveDirectoryIterator('.');
      $iterator       = new RecursiveIteratorIterator($directory_iterator);
    
      class CustomFilterIterator extends FilterIterator {
           function accept() {
                $current=$this->getInnerIterator()->current();
                return ($current->isFile()&&$current->getMTime()>time()-3600*24*7);
           }
      }
    
      $filter_iterator=new CustomFilterIterator($iterator);
      foreach ($filter_iterator as $file) {
         echo $file->getPathname() . PHP_EOL;
      }
    
    0 讨论(0)
提交回复
热议问题