我只是试图循环遍历目录中的所有文件,递归地过滤到仅匹配模式的文件。
结果 RegexIterator给你正则表达式匹配对象,但我想要 SplInfo
对象。
所以这是我得到的:
class RegexFilterIterator extends RecursiveFilterIterator {
private $pattern;
public function __construct(RecursiveIterator $iterator, $pattern) {
parent::__construct($iterator);
$this->pattern = $pattern;
}
public function accept() {
return preg_match($this->pattern, $this->current()->getFilename()) > 0;
}
}
$dir = new RecursiveDirectoryIterator($argv[1]);
$regex = new RegexFilterIterator($dir, '/\.php5?\z/i');
$it = new RecursiveIteratorIterator($regex);
foreach($it as $foo) {
echo $foo->getPathname().PHP_EOL;
}
但这似乎不是递归的。
我相信那是因为 \RegexFilterIterator::accept
实际上也被提供给目录,我拒绝它们,因为它们不以 .php
结尾。
很容易修复,对吧?稍微修改一下:
public function accept() {
return $this->current()->isDir() || preg_match($this->pattern, $this->current()->getFilename()) > 0;
}
现在它崩溃了:
PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function RegexFilterIterator::__construct(), 1 passed and exactly 2 expected in bleep
这对我来说没有任何意义。为什么要尝试自己构造更多 RegexFilterIterator
实例,它是如何搞砸的??
我将 RegexFilterIterator
放在 RecursiveIteratorIterator
之后,但它对我大喊大叫:
PHP Fatal error: Uncaught TypeError: Argument 1 passed to RegexFilterIterator::__construct() must implement interface RecursiveIterator, instance of RecursiveIteratorIterator given
所以...我不知道您应该如何使用这些类。
我如何递归目录中的所有文件,并使用简单的正则表达式过滤它们,返回生成 SplInfo 对象的生成器/可迭代对象?
最佳答案
找到 this埋在 php.net 上的评论中,由“sun”发布,并对其进行了一些改进:
$directory = new \RecursiveDirectoryIterator($argv[1], \FilesystemIterator::SKIP_DOTS);
$filter = new \RecursiveCallbackFilterIterator($directory, function ($current, $key, $iterator) {
return $current->isDir() || preg_match('/\.php5?\z/',$current->getPathname()) > 0;
});
$iterator = new \RecursiveIteratorIterator($filter);
foreach($iterator as $file) {
echo $file->getPathname().PHP_EOL;
}
RecursiveCallbackFilterIterator
似乎更容易使用,而不是扩展 RecursiveFilterIterator
。还有一个方便的 FilesystemIterator::SKIP_DOTS
标志。
关于PHP递归正则表达式过滤器迭代器迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48574831/