php无法底层恢复已删文件,仅支持逻辑恢复:前提是有回收站(如移至/trash/并校验路径)、tar备份(用phardata流式提取)或系统工具(如extundelete,但高风险需离线操作)。

PHP批量恢复被误删文件的前提很有限
PHP本身不能从磁盘底层找回已删除的文件,它只能在有备份、回收站机制或文件系统支持快照的前提下做“逻辑恢复”。如果你的服务器没配Volume Shadow Copy(Windows)或没启用Btrfs/ZFS快照,也没有定期备份到$backup_dir,那么file_put_contents或copy再快也写不回已经释放的磁盘块。
用PHP还原「用户级回收站」里的文件
这是最常见且可控的场景:你事先把用户删除操作转为移动到/var/www/app/trash/目录,并记录原始路径和时间戳。恢复时只需按记录批量移回。
实操要点:
- 恢复前必须校验
$trash_record中每个original_path是否合法(不能含../、不能超出web根目录) - 用
realpath和str_starts_with双重判断目标路径是否在允许范围内,避免路径遍历 - 优先用
rename而非copy + unlink,减少I/O和失败风险 - 记录恢复日志到
/var/log/php-restore.log,包含filemtime和操作者ID
示例片段:
// $records = [['id'=>1, 'original_path'=>'/uploads/photo.jpg', 'trash_path'=>'/trash/20240512_abc.jpg']];
foreach ($records as $r) {
$safe_target = realpath($_SERVER['DOCUMENT_ROOT'] . $r['original_path']);
if (!$safe_target || !str_starts_with($safe_target, $_SERVER['DOCUMENT_ROOT'])) {
error_log("Reject restore: unsafe path {$r['original_path']}");
continue;
}
if (rename($r['trash_path'], $safe_target)) {
chmod($safe_target, 0644); // 恢复权限
}
}
从tar.gz备份包中提取指定文件
当备份是周期性生成的backup_20240510.tar.gz,而你只需要恢复其中几个.log或.json文件时,别解压整个包——用phar扩展直接流式提取更安全高效。
注意点:
- 确保
phar.readonly = 0在php.ini中关闭,否则PharData无法读取压缩包 -
PharData::extractTo()不支持通配符,需先getIterator()遍历筛选getFilename() - 提取目标目录必须存在且可写,否则抛出
PharException - 大包下用
setArchiveFormat(Phar::GZ)显式声明格式,避免自动探测失败
关键代码:
$phar = new PharData('/backups/backup_20240510.tar.gz');
$files_to_restore = ['config.json', 'data/export.csv'];
foreach ($phar as $file) {
if (in_array($file->getFilename(), $files_to_restore)) {
$phar->extractTo('/var/www/app/', $file->getFilename(), true);
}
}
Linux下调用extundelete或photorec的边界风险
PHP可通过shell_exec调用这些工具,但生产环境强烈不建议:它们需要root权限、会扫描整块设备、恢复结果不可控(文件名丢失、内容碎片化),且exec超时或输出截断极易导致脚本卡死。
如果真要走这条路:
- 只在离线维护窗口期运行,且限定设备分区如
/dev/sdb1,绝不用/dev/sda - 用
proc_open捕获完整stderr,匹配"Failed to open device"或"No partition table"等错误 - 恢复出的文件默认存到
/tmp/undelete_$$/($$是当前进程PID),避免并发冲突 - 执行前检查
disk_free_space是否大于预估恢复体积的3倍——photorec临时空间吃得很凶
这类操作不是“PHP功能”,而是拿PHP当胶水调用系统工具,一旦出错,恢复动作本身可能造成二次覆盖。
真正容易被忽略的是时间窗口:从文件删除到开始恢复的间隔越短越好。NTFS下可能撑几小时,ext4若触发日志刷盘或有新写入,几分钟后元数据就不可逆了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











