登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  php教程

PHP CallbackFilterIterator 按文件属性过滤目录项的写法

来源:17golang原创

时间:2026-11-14 05:14:06 494浏览 收藏

PHP CallbackFilterIterator 按文件属性过滤目录项,关键是把“遍历”交给 FilesystemIterator,把“是否保留当前项”交给回调。回调返回 true 时保留当前目录项,返回 false 时排除;文件类型、扩展名和大小都可以从 SplFileInfo 读取。

官方文档:https://www.php.net/manual/en/callbackfilteriterator.construct.php

如果只筛当前目录,用 CallbackFilterIterator 包装 FilesystemIterator 就够了;如果还要进入子目录,应改用 RecursiveCallbackFilterIterator,并单独决定哪些目录允许继续展开。
要点速览
  • 内层迭代器提供当前值,过滤器不负责扫描目录。
  • 文件属性判断集中写在回调里,返回值只表达接受或排除。
  • 浅层遍历和递归遍历是两个范围问题,不要只改回调条件。

先把目录迭代器和筛选回调分开

CallbackFilterIterator 接受一个已有的 Iterator 和一个回调。下面的内层迭代器使用 FilesystemIterator,因此回调收到的当前值可以按 SplFileInfo 使用。这样做的好处是:目录如何前进、当前条目是否合格,两件事不会混在一段手写循环里。

isFile()
            && strtolower($file->getExtension()) === 'php'
            && $file->getSize() getRealPath(), PHP_EOL;
}
PHP CallbackFilterIterator 从目录根路径、FilesystemIterator 到 SplFileInfo 和 accepted items 的静态关系说明图
图1:CallbackFilterIterator 过滤链的静态说明图,不是运行截图或执行证据。

示例中的 SKIP_DOTS 只排除 . 和 ..,并不会自动递归。CURRENT_AS_FILEINFO 保证当前值按文件信息对象理解;如果改了迭代器 flags,就应重新确认回调参数类型。

按 SplFileInfo 属性过滤时回调接收什么

官方说明中,过滤回调可观察当前值、当前键和内层迭代器。当前值是这里最重要的输入:isFile() 判断条目类型,getExtension() 取得后缀,getSize() 取得文件大小。不要用文件名后缀代替 isFile(),否则目录名或特殊条目可能被误当成可处理文件。

判断点返回 true 的含义常见边界
isFile()当前项是普通文件目录和其他文件系统条目会被排除
getExtension()后缀符合规则大小写要先统一
getSize()大小不超过阈值阈值要和业务处理能力一致
回调返回值true 保留,false 排除不是修改原目录,也不是终止遍历

回调可以声明更宽的参数类型,再在函数体里判断对象;但对这个场景,使用 SplFileInfo 能把意图写在签名上。过滤器只改变外层迭代器看到的集合,不会删除磁盘上的文件,也不会替你处理权限异常。

回调参数和递归边界怎么判断

需要进入子目录时,问题就从“当前项是否保留”扩展成“哪些目录可以继续展开”。此时使用 RecursiveDirectoryIterator 配合 RecursiveCallbackFilterIterator,在回调中对目录和文件分别处理。若只需要当前目录的文件,继续使用前面的浅层方案更容易控制权限、耗时和误扫范围。

PHP CallbackFilterIterator 的 current、key、inner iterator 与递归过滤范围关系说明图
图2:回调参数与浅层/递归过滤边界的关系说明图,不是运行截图或执行证据。

实战里可以按下面的清单收尾:先确认内层迭代器类型,再确认当前值是否为 SplFileInfo;随后检查回调是否始终返回布尔值,最后明确是否允许进入子目录。这样排错时,不会把“条件没命中”和“根本没有遍历到子目录”混为一谈。

常见问题

CallbackFilterIterator 会删除不符合条件的文件吗?

不会。它只在迭代结果中排除当前项,不改变目录内容。

为什么回调里拿不到文件属性?

先检查内层迭代器和 flags。使用 FilesystemIterator 的文件信息模式,当前值才适合直接调用 SplFileInfo 方法。

怎样过滤子目录里的文件?

改用递归迭代器组合,并在回调里同时定义目录展开条件和文件接受条件;不要把浅层 CallbackFilterIterator 当成递归器。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>