我只是试图递归地遍历目录中的所有文件,只过滤那些与模式匹配的文件。
结果是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致命错误:未捕获ArgumentCountError:函数RegexFilterIterator::__construct()的参数太少,已传递%1,但在bleep中应恰好为%2
这对我来说没有任何意义。为什么试图自己构造更多的RegexFilterIterator
实例,以及它是如何搞砸的?
PHP致命错误:未捕获TypeError:传递给RegexFilterIterator::__construct()的参数1必须实现给定的RecursiveIteratorIterator实例的接口RecursiveIterator
所以..。我不知道您应该如何使用这些类。
我如何递归一个目录中的所有文件,并用一个简单的正则表达式过滤它们,返回一个生成SplInfo对象的生成器/迭代器?
发布于 2018-02-03 01:19:56
在"sun“发布的php.net评论中发现了this,并对其进行了改进:
$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;
}
与扩展RecursiveFilterIterator
相比,RecursiveCallbackFilterIterator
似乎更容易使用。还有一个很方便的FilesystemIterator::SKIP_DOTS
标志。
发布于 2018-02-02 10:33:45
我意识到我们可以只使用一个生成器函数来清理这种无意义的东西,而不是浪费在迭代器接口上:
function readDirRecursive($dir, $pattern=null) {
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS));
foreach($iterator as $it) {
if($it->isFile() && ($pattern===null || preg_match($pattern, $it->getPathname()))) {
yield $it;
}
}
}
$iterator = readDirRecursive($argv[1],'/\.php5?\z/');
foreach($iterator as $file) {
echo $file->getPathname().PHP_EOL;
}
https://stackoverflow.com/questions/48574831
复制相似问题