You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);

关键说明

  1. 安全校验:通过realpath验证目录合法性,防止恶意用户通过../等路径访问服务器上的敏感目录。
  2. 哈希映射结构:用哈希作为键,能快速将所有内容相同的文件归类,比原数组结构更高效。
  3. 删除逻辑:默认保留每组中的第一个文件,你可以根据需求调整保留规则(比如保留最新修改的文件,可通过filemtime判断)。

内容的提问来源于stack exchange,提问作者Doomish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 09:23:07