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

2022-08-30 18:02:16

我已经设置了一个基本脚本,该脚本正在发布一个路径数组以在其中查找模板文件;目前,它只搜索了两个级别的深度,我遇到了一些麻烦,我很难弄清楚一个广泛循环的逻辑,以迭代所有子目录,直到长度为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

它只在“侧面”目录中搜索.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));
?>

答案 1

PHP内置了适合您的完美解决方案。

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

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

资源


答案 2

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

可以使用 RecursiveDirectoryIterator 以递归方式循环访问目录。

您可以对结果使用递归迭代器Iterator来获得结果的平展视图。

您可以在结果上使用正则表达式进行筛选。

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

推荐