foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(".")) as $file) {
echo "$file\n";
}
Is there any way for this code to not throw UnexpectedValueException "failed to open dir: Permission denied" whenever there is a unreadable subdirectory inside directory I attempt to list?
有没有办法让这个代码不会抛出UnexpectedValueException“无法打开目录:权限被拒绝”只要目录中有一个不可读的子目录我尝试列出?
UPDATE
Converting foreach()
to while()
and explicitly calling Iterator::next()
wrapped in try() catch {}
doesn't help. This code:
将foreach()转换为while()并显式调用try()catch {}中包含的Iterator :: next()没有帮助。这段代码:
$iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("."));
while($iter->valid()) {
$file = $iter->current();
echo "$file\n";
try {
$iter->next();
} catch(UnexpectedValueException $e) {
}
};
is an infinite loop if there is unreadable subdirectory.
如果存在不可读的子目录,则是无限循环。
3 个解决方案
#1
19
Apparently you can pass $flags
parameter to constructor. There's only one flag in the docs, but it does exactly what you want: catches exceptions during getChildren() calls and simply jumps to the next element
.
显然你可以将$ flags参数传递给构造函数。文档中只有一个标志,但它完全符合您的要求:在getChildren()调用期间捕获异常并简单地跳转到下一个元素。
Change your class creation code to
将您的类创建代码更改为
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator("."),
RecursiveIteratorIterator::LEAVES_ONLY,
RecursiveIteratorIterator::CATCH_GET_CHILD);
and it should work
它应该工作
#2
7
You could do something like this :
你可以这样做:
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";
}
#3
-1
It's possible that the iterator position will still be valid even if a directory is not readable.
即使目录不可读,迭代器位置仍可能有效。
You could check the state of the directory entry. Sloppy untested sample code:
您可以检查目录条目的状态。邋un的未经测试的示例代码:
$iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("."));
foreach ($iter as $dir) {
if($dir->isReadable()){
//do something
}
}
#1
19
Apparently you can pass $flags
parameter to constructor. There's only one flag in the docs, but it does exactly what you want: catches exceptions during getChildren() calls and simply jumps to the next element
.
显然你可以将$ flags参数传递给构造函数。文档中只有一个标志,但它完全符合您的要求:在getChildren()调用期间捕获异常并简单地跳转到下一个元素。
Change your class creation code to
将您的类创建代码更改为
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator("."),
RecursiveIteratorIterator::LEAVES_ONLY,
RecursiveIteratorIterator::CATCH_GET_CHILD);
and it should work
它应该工作
#2
7
You could do something like this :
你可以这样做:
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";
}
#3
-1
It's possible that the iterator position will still be valid even if a directory is not readable.
即使目录不可读,迭代器位置仍可能有效。
You could check the state of the directory entry. Sloppy untested sample code:
您可以检查目录条目的状态。邋un的未经测试的示例代码:
$iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("."));
foreach ($iter as $dir) {
if($dir->isReadable()){
//do something
}
}