PHP通过哈希查找并删除重复文件:现有代码后续步骤求助
修复代码并实现重复文件查找与删除
首先你的现有代码存在几个问题:
- 数组存储结构错误:把文件名和哈希值作为独立元素存入数组,导致无法对应每个文件的哈希,后续没法准确识别重复文件。
- 变量名错误:
$aunique是笔误,应该是$uniques,且$result从未定义。 - 存在安全风险:直接使用
$_GET['name']拼接路径,容易被利用进行路径遍历攻击,需要先做输入校验。
修正后的实现思路
我们应该把哈希值作为数组的键,对应的文件路径列表作为值,这样相同哈希(即内容重复)的文件会自动归为一组。之后遍历每组文件,保留一个,删除其余重复项。
完整代码示例
// 安全处理输入:限制目录范围,避免路径遍历 $targetDir = $_GET['name'] ?? ''; // 转为绝对路径并验证是否在允许的目录内(这里假设允许当前脚本所在目录下的子目录) $safeDir = realpath($targetDir); if (!$safeDir || strpos($safeDir, realpath(__DIR__)) !== 0) { die('非法目录请求'); } // 构建哈希到文件列表的映射 $hashToFiles = []; $localfiles = glob($safeDir . '/*'); foreach ($localfiles as $localfile) { if (is_file($localfile)) { $fileHash = hash_file('sha256', $localfile); // 将文件路径添加到对应哈希的数组中 if (!isset($hashToFiles[$fileHash])) { $hashToFiles[$fileHash] = []; } $hashToFiles[$fileHash][] = $localfile; } } // 遍历哈希分组,处理重复文件 $deletedFiles = []; $keptFiles = []; foreach ($hashToFiles as $hash => $files) { if (count($files) > 1) { // 保留第一个文件,删除其余的 $keptFiles[] = $files[0]; for ($i = 1; $i < count($files); $i++) { $file = $files[$i]; // 先判断文件是否存在,再删除 if (file_exists($file) && unlink($file)) { $deletedFiles[] = $file; } else { echo "无法删除文件:$file\n"; } } } else { // 无重复的文件直接加入保留列表 $keptFiles[] = $files[0]; } } // 输出结果 echo "保留的文件:\n"; print_r($keptFiles); echo "\n删除的重复文件:\n"; print_r($deletedFiles);
关键说明
- 安全校验:通过
realpath验证目录合法性,防止恶意用户通过../等路径访问服务器上的敏感目录。 - 哈希映射结构:用哈希作为键,能快速将所有内容相同的文件归类,比原数组结构更高效。
- 删除逻辑:默认保留每组中的第一个文件,你可以根据需求调整保留规则(比如保留最新修改的文件,可通过
filemtime判断)。
内容的提问来源于stack exchange,提问作者Doomish
相关产品推荐
相关产品推荐

