rmdir只能删除空目录,因封装POSIX系统调用且无递归功能;删非空目录需用RecursiveDirectoryIterator配合CHILD_FIRST遍历后逐层删除,或严格过滤后调用系统命令。
PHP
为什么直接删非空目录会报错
函数设计上只接受**空目录**,只要目录里有哪怕一个文件、子目录、隐藏文件(比如
或
),调用就会失败,并抛出
。这不是 bug,是 POSIX 级别的行为约束——PHP 的
直接封装了系统调用,不处理递归逻辑。
常见错误现象:
返回
,但没报错(因错误报告级别设置),结果目录还在;或者开了
就看到满屏警告。
别指望
自带递归开关——它根本没有
参数
别先
再挨个
却忘了删子目录本身,最后
还是失败
Windows 下注意路径分隔符,但
和
都支持正斜杠,不用硬切
手动递归删除:用
最稳
这是 PHP 5.3+ 原生推荐方式,能自动跳过
和
,天然支持符号链接判断,且可捕获异常(比如权限不足)。比手写
更少漏掉隐藏文件或循环引用。
实操建议:
立即学习
“
PHP免费学习笔记(深入)
”;
用
包一层,把嵌套结构“拉平”,避免自己写递归函数
必须从最深层开始删(
),否则父目录删不掉
对每个
对象,先用
判断,再决定调用
还是
简短示例:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
用
调系统命令的坑要当心
Linux/macOS 下有人图快写
,看似一行解决,但风险集中:
如果含空格、换行或
,没过滤就拼进 shell,可能误删其他路径(命令注入)
Windows 不认
,得切
,跨平台维护成本陡增
Web 服务器(如 Apache/Nginx)通常禁用
类函数,线上环境大概率失败
即使成功,也绕过了 PHP 的 open_basedir 限制和用户权限检查,安全策略形同虚设
除非你完全控制运行环境、输入绝对可信、且明确需要删巨量小文件(此时系统命令确实更快),否则别碰。
删之前必须检查的三件事
递归删除不可逆,一旦执行就无法撤回。容易被忽略但实际高频出问题的点:
确认
是绝对路径,相对路径在 CLI 和 Web 下行为不一致(比如
比
安全得多)
检查目标是否为软链接——
为
时,
会删链接本身,不是链接指向的目录
留意 SELinux 或容器环境下的权限模型:即使 PHP 进程有写权限,也可能被策略拦截,此时
静默失败,需查
或系统日志
删生产目录前,至少
一遍路径,肉眼核对;批量操作加
开关保命。
rmdirrmdir.git.DS_StoreWarning: rmdir(): Directory not emptyrmdirrmdir('/path/to/dir')falseE_WARNINGrmdir$recursivescandirunlinkrmdirrmdirunlink\RecursiveDirectoryIterator...scandir + foreachRecursiveIteratorIteratorRecursiveIteratorIterator::CHILD_FIRSTSplFileInfoisDir()unlink()rmdir()function rrmdir($dir) {
$iter = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($iter as $file) {
if ($file->isDir()) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
return rmdir($dir);
}execexec("rm -rf $dir")$dir*rm -rfrd /s /qexec$dir__DIR__ . '/cache''./cache'is_link($dir)truermdirrmdirgetlasterror()echoif (false) { ... }