我可以让RecursiveDirectoryIterator跳过不可读的目录吗?

Kam*_*zot 15 php directory directory-walk

foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(".")) as $file) {
  echo "$file\n";
}
Run Code Online (Sandbox Code Playgroud)

有没有办法让这个代码不会抛出UnexpectedValueException"无法打开dir:权限被拒绝"只要目录中有一个不可读的子目录我试图列出?

UPDATE

转换foreach()while()显式调用Iterator::next()包装try() catch {} 并没有帮助.这段代码:

$iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("."));
while($iter->valid()) {
    $file = $iter->current();
    echo "$file\n";
    try {
        $iter->next();
    } catch(UnexpectedValueException $e) {
    }
};
Run Code Online (Sandbox Code Playgroud)

如果存在不可读的子目录,则是无限循环.

Ger*_*umm 19

显然你可以将$flags参数传递给构造函数.文档中只有一个标志,但它完全符合您的要求:catches exceptions during getChildren() calls and simply jumps to the next element.

将您的类创建代码更改为

new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator("."), 
    RecursiveIteratorIterator::LEAVES_ONLY,
    RecursiveIteratorIterator::CATCH_GET_CHILD);
Run Code Online (Sandbox Code Playgroud)

它应该工作


小智 7

你可以这样做:

class ReadableFilter extends RecursiveFilterIterator{
    public function accept(){
            return $this->current()->isReadable();
    }
}

$filteredIterator = new RecursiveIteratorIterator(new ReadableFilter(new RecursiveDirectoryIterator(".")));

foreach ($filteredIterator as $file){
    echo "$file\n";
}
Run Code Online (Sandbox Code Playgroud)