我有以下非常简单的RecursiveDirectoryIterator代码:
$dir = new RecursiveDirectoryIterator('/Users/yivi/test/', RecursiveDirectoryIterator::KEY_AS_PATHNAME);
$iter = new RecursiveIteratorIterator($dir);
foreach ($iter as $item) {
if ($item->isDir()) {
echo $item->getPath() . "\n";
$countd ++;
} else {
$count++;
}
}
echo "$count files and $count directories";
但产生以下输出:
/Users/yivi/Sites/test
/Users/yivi/Sites/test
/Users/yivi/Sites/test/01
/Users/yivi/Sites/test/01
/Users/yivi/Sites/test/02
/Users/yivi/Sites/test/02
/Users/yivi/Sites/test/03
/Users/yivi/Sites/test/03
/Users/yivi/Sites/test/03/ab
/Users/yivi/Sites/test/03/ab
/Users/yivi/Sites/test/03/cd
/Users/yivi/Sites/test/03/cd
40 files and 12 directories
当我退出循环时,我计算了每个目录两次(我得到双重列表,$ countd是12,而不是6)。
为什么这样做?如何避免呢?
我尝试使用RecursiveDirectoryIterator::SKIP_DOTS
作为标志,但随后它会跳过所有目录(但会对文件进行计数)。
(PHP 5.5)
答案 0 :(得分:1)
TL; DR 使用RecursiveIteratorIterator::SELF_FIRST
作为迭代模式,以及RecursiveDirectoryIterator::SKIP_DOTS
标记。
您看到两行,因为$item
值适用于"。"和" .."项目,并且尝试使用SKIP_DOTS
是正确的,因为您很可能希望跳过这些项目。
然而,RecursiveIteratorIterator
的默认行为是仅迭代" leaf"项目(即不包含更多项目的项目)而非一切,有效地跳过目录。
所以,你需要告诉RecursiveIteratorIterator
使用不同的模式,而不是默认的"只留下" mode:" self first"或者"孩子先"。
$iter = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::SELF_FIRST);
回到原始代码,您可以通过回显$item->getPathname()
(或简单地回显$item
在这里工作)来查看正在进行的操作。那将显示"点目录"你需要跳过。