php无法恢复已删除的文件夹,因其仅调用系统unlink(2)/rmdir(2),无回收站访问、快照或扇区扫描能力;恢复依赖系统工具(如extundelete)、备份(time machine、zfs快照)或运维协同。

PHP 本身不能恢复已删除的文件夹——它没有访问操作系统回收站或文件系统快照的能力,也不具备底层磁盘扇区扫描功能。
PHP 调用 unlink() 或 rmdir() 后文件夹就彻底没了
PHP 的 unlink()、rmdir() 和 rrmdir()(自定义递归)都是直接调用系统 unlink(2) 或 rmdir(2) 系统调用。Linux/macOS 下没有回收站概念;Windows 上即使启用了回收站,PHP 也不会自动走 IFileOperation 接口,而是直删。
- 常见错误现象:
Warning: rmdir(): Directory not empty或静默删除成功,但发现没备份、不可逆 - 使用场景:写部署脚本、临时目录清理、CMS 插件卸载逻辑时容易误用
rmdir($path, true)(注意:PHP 原生rmdir()不支持第二个参数,这是常见混淆点) - 参数差异:
rmdir()只能删空目录;想删非空目录必须自己遍历 +unlink()+rmdir(),且无回滚机制
真要“恢复”,得靠系统层或备份机制,不是 PHP 能干的
PHP 是运行在用户态的应用层程序,它不持有已删除文件的 inode 引用,也无法拦截或撤回系统调用。所谓“恢复”,本质是外部干预:
- Linux:立即停写磁盘,用
extundelete(ext3/4)、photorec(通用,但无文件名)等工具抢救,依赖未被覆盖 - macOS:检查
.Trashes目录(需有权限且未清空),或 Time Machine 备份 - Windows:检查回收站(路径如
C:\$Recycle.Bin\...),或用recuva等工具 - 服务器环境:唯一靠谱路径是定期
rsync到另一位置,或启用 ZFS/Btrfs 快照 —— PHP 可以调用shell_exec('zfs rollback pool/fs@snap1'),但这属于运维协同,不是 PHP 自身能力
预防比恢复重要:PHP 层该做的安全防护
既然恢复不可控,就在删除前加约束。别指望“删错了再找回来”,要让误删根本删不出去:
立即学习“PHP免费学习笔记(深入)”;
- 强制校验路径白名单:
if (!in_array(realpath($dir), $allowed_dirs)) { die('Forbidden'); } - 禁用生产环境绝对路径硬编码:用配置项
APP_STORAGE_ROOT替代/var/www/html/uploads,避免脚本里写死rmdir('/var/www') - 模拟删除(dry-run):开发期加开关,把
rmdir()换成echo "[DRY] Would remove: $dir",上线前关掉 - 记录操作日志:删除前写入
error_log("rmdir triggered by {$user} on {$dir} at " . date('c')),至少知道谁、啥时、删了啥
真正棘手的不是“怎么用 PHP 恢复”,而是删之前没做路径校验、没开日志、没配备份 —— 这些环节一旦漏掉,后面所有补救都靠运气。











