无法使用RecursiveDirectoryIterator跳过不可读的目录

ak8*_*k85 9 php directory directory-walk

我想得到所有子目录的列表,我的下面的代码工作,除非我对某些文件夹具有只读权限.

在下面的问题中,它显示了如何使用RecursiveDirectoryIterator跳过目录 我可以使RecursiveDirectoryIterator跳过不可读的目录吗?但是我的代码在这里略有不同,我无法解决问题.

$path = 'www/';
foreach (new RecursiveIteratorIterator(
       new RecursiveDirectoryIterator($path,RecursiveDirectoryIterator::KEY_AS_PATHNAME),
            RecursiveIteratorIterator::CHILD_FIRST) as $file => $info) 
            {
                if ($info->isDir())
                {
                       echo $file . '<br>';                     
                }
            }   
Run Code Online (Sandbox Code Playgroud)

我收到了错误

Uncaught exception 'UnexpectedValueException' with message 'RecursiveDirectoryIterator::__construct(../../www/special): failed to open dir: Permission denied'
Run Code Online (Sandbox Code Playgroud)

我试过用另一个问题中接受的答案替换它.

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

但是这段代码不会给我一个像我想要的www里面所有目录的列表,我在哪里错了?

Bab*_*aba 6

介绍

您的代码的主要问题是使用 CHILD_FIRST

来自PHP DOC

可选模式.可能的值是

  • RecursiveIteratorIterator :: LEAVES_ONLY - 默认值.列表仅在迭代中离开.
  • RecursiveIteratorIterator :: SELF_FIRST - 在父级出现的情况下迭代叶子和父级.
  • RecursiveIteratorIterator :: CHILD_FIRST - 在迭代中列出叶子和父项,叶子首先出现.

您应该使用的SELF_FIRST是包含当前目录.您还忘记添加可选参数RecursiveIteratorIterator::CATCH_GET_CHILD

来自PHP DOC

可选标志.可能的值是RecursiveIteratorIterator :: CATCH_GET_CHILD,它将忽略对RecursiveIteratorIterator :: getChildren()的调用中抛出的异常.

您的CODE重新访问

foreach (new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path,RecursiveDirectoryIterator::KEY_AS_PATHNAME),
        RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD) as $file => $info)
{
    if ($info->isDir())
    {
        echo $file . '<br>';
    }
}
Run Code Online (Sandbox Code Playgroud)

你真的想要 CHILD_FIRST

如果你真的想保持CHILD_FIRST结构,那么我建议你使用ReadableDirectoryIterator

foreach ( new RecursiveIteratorIterator(
        new ReadableDirectoryIterator($path),RecursiveIteratorIterator::CHILD_FIRST) as $file ) {
    echo $file . '<br>';
}
Run Code Online (Sandbox Code Playgroud)

使用的类

class ReadableDirectoryIterator extends RecursiveFilterIterator {
    function __construct($path) {
        if (!$path instanceof RecursiveDirectoryIterator) {
            if (! is_readable($path) || ! is_dir($path))
                throw new InvalidArgumentException("$path is not a valid directory or not readable");
            $path = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
        }
        parent::__construct($path);
    }

    public function accept() {
        return $this->current()->isReadable() && $this->current()->isDir();
    }
}
Run Code Online (Sandbox Code Playgroud)