unlink() 仅能删除文件而非目录,失败时返回 false 且不报错原因;需检查路径存在性、父目录写权限、文件是否被占用,并注意跨平台路径与权限差异。

unlink() 不能直接删目录,只能删文件;调用失败时默认抛 E_WARNING,不 throw 异常,也不自动告诉你为什么失败——得自己检查路径、权限、打开状态。
文件不存在或路径写错时 unlink() 会静默失败
它返回 false,但不会说明是“没找到”还是“没权限”。常见错误现象:明明文件在浏览器里能访问,unlink() 却返回 false。
- 先用
file_exists($path)确认路径存在,注意:相对路径是相对于当前执行脚本的位置,不是 Web 根目录或 CLI 当前工作目录 - 用
realpath($path)打印真实路径,避免软链、..或符号干扰 - Windows 下路径分隔符用
/或\都行;Linux 下必须用/,且大小写敏感 - 如果路径来自用户输入(比如表单传的
filename),务必过滤或白名单校验,防止路径遍历(如../../../etc/passwd)
权限不足是 Linux 服务器上最常踩的坑
很多人本地测试成功,上线就失败。根本原因不是 PHP 没权限删文件,而是**文件所在目录缺少写权限**。
-
unlink()实际需要的是「父目录」的写权限(w),不是文件本身的权限——这点和 Unixrm行为一致 - 用
ls -ld /path/to/dir查看目录权限,确保运行 PHP 的用户(如www-data或nginx)有w权限 - ACL 场景下,还需确认父目录有
delete_child权限,仅delete不够(OS X / FreeBSD 类系统尤其明显) - 临时解决可
chmod 755 /path/to/dir,但生产环境应最小权限原则,改属组更稳妥
文件正被占用时 unlink() 行为因系统而异
PHP 7.3+ 在 Windows 上已支持删除正在被读写的文件(如日志文件),但 Linux 不行——只要还有进程持有该文件描述符,unlink() 虽返回 true,磁盘空间也不会释放。
- 用
lsof +D /path/to/dir查是否有进程锁着目标文件 - Web 服务中常见于:文件刚被
fopen('a')打开写入但未fclose();或被file_get_contents()加载后未释放引用 - PHP-FPM 模式下,注意
opcache.enable_cli=0等配置可能影响文件句柄生命周期 - 不要依赖
unlink()返回true就认为磁盘已腾出空间;大文件删完建议补一句clearstatcache(true, $path)
批量删文件别硬写循环,优先用 glob + array_map
想删 uploads/2026/* 下所有 .tmp 文件?不用 opendir() + readdir() 套三层 if。
// 一行安全删匹配文件(注意 glob 不递归)
array_map('unlink', glob(__DIR__ . '/uploads/2026/*.tmp'));
// 更健壮的写法:过滤掉 glob 失败或空结果
$files = glob(__DIR__ . '/uploads/2026/*.tmp');
if ($files !== false) {
foreach ($files as $file) {
@unlink($file); // @ 抑制 warning,实际项目建议记录日志
}
}
注意:glob() 不支持正则,只认 shell 通配符;** 递归需加 GLOB_BRACE 和 PHP 5.6+;大量小文件时,array_map('unlink', ...) 比 foreach 略快,但差别不大。
unlink() 成功只代表“名字被摘除”,不等于“数据块被回收”。线上清理任务务必加空间检查兜底。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











