
用 scandir() 最快扫出所有文件,但默认包含 . 和 ..
直接调 scandir() 能拿到文件夹下所有条目,但它一定会返回 .(当前目录)和 ..(父目录),不剔除就会在后续处理里报错或跳过真实文件。
- 用
array_diff()剔除:array_diff(scandir($path), ['.', '..']) - 别用
foreach里手动continue判字符串——容易漏掉其他隐藏文件(比如.gitignore) -
scandir()返回的是无序列表,如需按字母/时间排序,得额外调sort()或usort()
递归遍历必须自己写函数,PHP 没有内置「深度遍历」开关
scandir() 只扫一层,要进子目录就得手动判断类型、再调自己。PHP 的 RecursiveDirectoryIterator 虽然能递归,但对象接口重、容错差,一不小心就抛 UnexpectedValueException。
- 推荐手写轻量递归:先
is_dir()再scandir(),遇到子目录就 call 自己 - 注意避免无限递归:检查
is_link()防软链接循环,尤其是 Linux 环境下可能有/proc/self这类自指路径 - 不要在递归里反复拼接路径字符串,用
realpath()或dirname()+basename()更稳
遇到权限不足或符号链接时,opendir() 会静默失败
scandir() 在没权限的目录里会返回 false,但不报错;而 opendir() + readdir() 方式更可控,能配合 @ 抑制警告,再用 is_readable() 提前守门。
- 先
if (!is_readable($path)) { return []; },比硬闯安全得多 - 对符号链接,默认不跟随,要用
is_dir($path) && !is_link($path)显式排除,否则scandir()可能崩在挂载点或损坏链接上 - Windows 下路径分隔符用
/完全没问题,别硬切\,PHP 内部自动兼容
大目录下用 glob() 替代 scandir() 更省内存
当只要某类文件(比如所有 .php),glob($path . '/*.php') 比先扫全量再 preg_match() 过滤快得多,且 PHP 内部用系统 readdir() 实现,不常驻内存。
立即学习“PHP免费学习笔记(深入)”;
-
glob()不支持递归,想搜子目录得加GLOB_BRACE和**(PHP 7.1+),但部分旧服务器禁用** - 路径里含变量时务必
escapeshellarg()?不用——glob()不走 shell,但变量本身得确保是合法路径,建议用realpath()校验 - 空结果返回空数组,不是
false,别用=== false判错
error_log() 打点日志比加 try/catch 更管用。











