【问题标题】:RecursiveDirectoryIterator in PHP, getting each directory twice in foreachPHP中的RecursiveDirectoryIterator,在foreach中获取每个目录两次
【发布时间】:2016-06-11 08:23:43
【问题描述】:

我有以下非常简单的 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)

【问题讨论】:

  • 我个人不知道如何在课程的核心解决它,但要绕过它(如果你赶时间)输出到一个数组然后array_unique()
  • 是的,我也可以想到其他快速修复,但主要是我想了解这种行为。还是谢谢!
  • 是的,我听到了。我在迭代器中遇到了类似这样的奇怪行为,我只是快速而肮脏地修复它们,所以我也对如何在类级别修复这种特殊行为感兴趣。

标签: php iterator php-5.5 spl


【解决方案1】:

TL;DR 使用RecursiveIteratorIterator::SELF_FIRST 作为迭代模式,以及RecursiveDirectoryIterator::SKIP_DOTS 标志。


您会看到两行,因为$item 的值用于“。”和“..”项目,并且尝试使用SKIP_DOTS 是正确的,因为您很可能确实想跳过这些项目。

但是,RecursiveIteratorIterator 的默认行为是仅遍历“叶”项(即不包含更多项的项)而不是所有内容,从而有效地跳过目录。

因此,您需要告诉RecursiveIteratorIterator 使用不同的模式,而不是默认的“仅离开”模式:“自我优先”或“孩子优先”之一。

$iter = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::SELF_FIRST);

回到您的原始代码,您可以通过回显$item->getPathname() 来查看发生了什么(或者在这里简单地回显$item 也可以)。这将显示您需要跳过的“点目录”。

【讨论】:

    猜你喜欢
    • 2019-08-28
    • 1970-01-01
    • 2023-03-18
    • 2016-06-21
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    • 2015-11-24
    • 2011-08-03
    相关资源
    最近更新 更多