有几种不同的方法可以做到这一点,我会给你两种快速的方法供你选择:快速和肮脏,而不是更长和不那么脏(虽然,这是一个星期五晚上,所以我们被允许有点疯狂)。
1.快速(和肮脏)
这涉及只需编写一个正则表达式(可以拆分为多个),用于一次快速筛选文件集合。
(只有两行注释对概念真正重要。
$directory = new RecursiveDirectoryIterator(__DIR__);
$flattened = new RecursiveIteratorIterator($directory);
// Make sure the path does not contain "/.Trash*" folders and ends eith a .php or .html file
$files = new RegexIterator($flattened, '#^(?:[A-Z]:)?(?:/(?!\.Trash)[^/]+)+/[^/]+\.(?:php|html)$#Di');
foreach($files as $file) {
echo $file . PHP_EOL;
}
这种方法存在许多问题,尽管它很快就实现了只是一个单行代码(尽管正则表达式可能很难破译)。
2.速度更慢(更脏)
一种更可重用的方法是创建几个定制的过滤器(使用正则表达式,或任何你喜欢的东西!)来减少初始中的可用项目列表,使其仅减少到你想要的项目。下面只是一个示例,专门为您快速编写,扩展 .RecursiveDirectoryIterator
RecursiveRegexIterator
我们从一个基类开始,其主要工作是保留我们要过滤的正则表达式,其他所有内容都推迟到 .请注意,该类是因为它实际上不做任何有用的事情:实际的过滤将由两个类完成,这将扩展这个类。此外,它可能被调用,但没有任何东西强迫它(在这个级别)过滤与文件系统相关的类(如果我不那么困倦,我会选择一个更好的名字)。RecursiveRegexIterator
abstract
FilesystemRegexFilter
abstract class FilesystemRegexFilter extends RecursiveRegexIterator {
protected $regex;
public function __construct(RecursiveIterator $it, $regex) {
$this->regex = $regex;
parent::__construct($it, $regex);
}
}
这两个类是非常基本的筛选器,分别作用于文件名和目录名。
class FilenameFilter extends FilesystemRegexFilter {
// Filter files against the regex
public function accept() {
return ( ! $this->isFile() || preg_match($this->regex, $this->getFilename()));
}
}
class DirnameFilter extends FilesystemRegexFilter {
// Filter directories against the regex
public function accept() {
return ( ! $this->isDir() || preg_match($this->regex, $this->getFilename()));
}
}
为了将这些内容付诸实践,以下内容以递归方式循环访问脚本所在的目录的内容(可以随意编辑它!)并筛选出文件夹(通过确保文件夹名称与特制的正则表达式匹配),并仅接受 PHP 和 HTML 文件。.Trash
$directory = new RecursiveDirectoryIterator(__DIR__);
// Filter out ".Trash*" folders
$filter = new DirnameFilter($directory, '/^(?!\.Trash)/');
// Filter PHP/HTML files
$filter = new FilenameFilter($filter, '/\.(?:php|html)$/');
foreach(new RecursiveIteratorIterator($filter) as $file) {
echo $file . PHP_EOL;
}
特别值得注意的是,由于我们的过滤器是递归的,我们可以选择如何迭代它们。例如,我们可以通过执行以下操作轻松地将自己限制为仅扫描最多2个级别(包括起始文件夹):
$files = new RecursiveIteratorIterator($filter);
$files->setMaxDepth(1); // Two levels, the parameter is zero-based.
foreach($files as $file) {
echo $file . PHP_EOL;
}
添加更多的过滤器(通过使用不同的正则表达式实例化更多的过滤类;或者,通过创建新的过滤类)以满足更专业的过滤需求(例如文件大小,完整路径长度等),这也是非常容易的。
P.S. 嗯,这个答案有点叽叽喳喳;我试图让它尽可能简洁(甚至删除了大量的超级胡言乱语)。如果最终结果使答案不连贯,请道歉。