如何递归迭代PHP中的文件?

时间:2014-09-18 10:08:44

标签: php loops

我已经设置了一个基本脚本,它发布了一系列路径来查找其中的模板文件;目前它只搜索两个级别,我有一些麻烦让我的头围绕逻辑​​进行广泛循环迭代所有子目录,直到长度为0。

所以,如果我有这样的结构:

./components
./components/template.html
./components/template2.html
./components/side/template.html
./components/side/template2.html
./components/side/second/template.html
./components/side/second/template2.html
./components/side/second/third/template.html
./components/side/second/third/template2.html

它只搜索" side" .html文件的目录,理想情况下,我希望它检查所有子目录和.html文件的传递目录。到目前为止,这是我的工作代码:

<?php
function getFiles($path){
    $dh  = opendir($path);
    foreach(glob($path.'/*.html') as $filename){
        $files[] = $filename;
    }
    if (isset($files)) {
        return $files;
    }
}
foreach ($_POST as $path) {
    foreach (glob($path . '/*' , GLOB_ONLYDIR) as $secondLevel) {
        $files[] = getFiles($secondLevel);
    }
    $files[] = getFiles($path);
}
sort($files);
print_r(json_encode($files));
?>

5 个答案:

答案 0 :(得分:31)

PHP为您提供了内置的完美解决方案。

实施例

// Construct the iterator
$it = new RecursiveDirectoryIterator("/components");

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

资源

答案 1 :(得分:5)

PHP 5引入了迭代器来快速遍历许多元素。

您可以使用RecursiveDirectoryIterator以递归方式遍历目录。

您可以对结果使用RecursiveIteratorIterator以获得结果的展平视图。

您可以对结果使用RegexIterator根据正则表达式进行过滤。

 $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;
 }

使用迭代器,有很多方法可以做同样的事情,你也可以使用FilterIterator(参见页面上的例子)

例如,如果要选择本周修改的文件,可以使用以下命令:

  $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;
  }

答案 2 :(得分:2)

另一种解决方案是使用Symfony的Finder组件。它经过测试和验证的代码。请在此处查看:http://symfony.com/doc/current/components/finder.html

答案 3 :(得分:1)

这是工作代码,它将给定目录$ dir及其所有子目录扫描到任何级别,并返回包含它们的html文件和文件夹列表。

<?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);

?>

答案 4 :(得分:0)

这是一个通用的解决方案:

function parseDir($dir, &$files=array(), $extension=false){

if(!is_dir($dir)){
    $info =  pathinfo($dir);
    // add all files if extension is set to false
    if($extension === false || (isset($info['extension']) && $info['extension'] === $extension)){
        $files[] = $dir;
    }
}else{
    if(substr($dir, -1) !== '.' && $dh =  opendir($dir)){
        while($file = readdir($dh)){
            parseDir("$dir/$file", $files, $extension);
        }
    }
}
 }

$files = array();
parseDir('components', $files, 'html');
var_dump($files);

输出

php parseDir.php 
array(7) {
  [0]=>
  string(25) "components/template2.html"
  [1]=>
  string(29) "components/side/template.html"
  [2]=>
  string(30) "components/side/template2.html"
  [3]=>
  string(36) "components/side/second/template.html"
  [4]=>
  string(37) "components/side/second/template2.html"
  [5]=>
  string(42) "components/side/second/third/template.html"
  [6]=>
  string(43) "components/side/second/third/template2.html"
}