如何用RecursiveFilterIterator筛选PHP中深度为2的子目录?
用RecursiveFilterIterator过滤仅深度为2的子目录
完全可以通过自定义RecursiveFilterIterator子类实现需求,不用在foreach里做判断。直接看实现代码和说明:
自定义深度过滤迭代器
首先创建继承自RecursiveFilterIterator的类,重写核心的accept方法来控制过滤规则,同时实现getChildren保证递归逻辑生效:
class DepthTwoDirectoryFilter extends \RecursiveFilterIterator { private $targetDepth = 2; public function accept() { $currentDepth = $this->getInnerIterator()->getDepth(); // 深度小于2时允许继续遍历子目录,才能到达目标层级 if ($currentDepth < $this->targetDepth) { return true; } // 刚好是深度2时,只保留目录类型的项 return $currentDepth === $this->targetDepth && $this->isDir(); } // 必须重写该方法,让子迭代器也应用相同过滤规则 public function getChildren() { return new self($this->getInnerIterator()->getChildren()); } }
最终使用代码
把自定义过滤器嵌套到迭代器链中,直接遍历即可输出目标目录:
$directory = "./test_dir"; // 基础目录迭代器,跳过.和.. $dirIterator = new \RecursiveDirectoryIterator( $directory, \FilesystemIterator::SKIP_DOTS ); // 应用自定义深度过滤 $filteredIterator = new DepthTwoDirectoryFilter($dirIterator); // 递归迭代器,SELF_FIRST模式保证遍历顺序符合需求 $iterator = new \RecursiveIteratorIterator( $filteredIterator, \RecursiveIteratorIterator::SELF_FIRST ); // 直接遍历输出,无需额外判断 foreach ($iterator as $file) { echo $file->getPathname() . "\n"; }
关键逻辑说明
accept方法是过滤核心:深度不足2时返回true,让迭代器继续向下遍历,这样才能触及到深度2的目录;到达深度2时,只筛选出目录类型的项;深度超过2的直接过滤。- 重写
getChildren是RecursiveFilterIterator的要求,确保每一层子目录都应用相同的深度过滤规则。 - 不需要再调用
setMaxDepth,过滤器已经完全控制了遍历的深度范围和内容类型。
内容的提问来源于stack exchange,提问作者Potivier
相关产品推荐
相关产品推荐

