我已经设置了一个基本脚本,它发布了一系列路径来查找其中的模板文件;目前它只搜索两个级别,我有一些麻烦让我的头围绕逻辑进行广泛循环迭代所有子目录,直到长度为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));
?>
答案 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"
}