PHP 文件写入去重:避免重复追加数据的完整解决方案

1次阅读

PHP 文件写入去重:避免重复追加数据的完整解决方案

本文详解如何在 php 中向文件写入数组数据时防止重复追加,涵盖清空重写、内容比对去重两种策略,并提供可直接运行的代码示例与关键注意事项。

在使用 file_put_contents() 向文件写入数据时,若反复执行且始终传入 FILE_appEND 标志,就会导致历史数据不断累积——正如问题中所示:每次运行脚本,Fanny, 1034 等记录都被重复追加,造成数据冗余。根本原因在于:FILE_APPEND 仅负责“追加”,不负责“判断是否已存在”。

✅ 方案一:覆盖写入(适用于每次全量更新场景)

若每次运行脚本都应以当前 $result 数组为唯一权威数据源(即旧数据完全失效),最简单高效的方式是移除 FILE_APPEND,让 file_put_contents() 默认以覆盖模式写入:

$dir = "C:/Users//data"; if (!is_dir($dir)) {     mkdir($dir, 0777, true); // 添加第三个参数 true 支持递归创建 }  $dataLines = []; foreach ($result as $item) {     // 注意:原代码中误用了 $data(应为 $asset),且部分键名为 asset_no     $name  = $item[0]['name'] ?? '';     $asset = $item[0]['asset'] ?? $item[0]['asset_no'] ?? '';     $dataLines[] = "$name, $asset"; }  // 覆盖写入(无 FILE_APPEND)→ 自动清除旧内容 file_put_contents("$dir/data", implode("rn", $dataLines) . "rn");

✅ 优点:简洁、高效、无读取开销;
⚠️ 注意:确保 $result 始终包含完整最新数据集,否则会丢失未包含的条目。

✅ 方案二:智能去重追加(适用于增量更新或需保留历史逻辑)

若需保留文件中已有数据,并仅追加 $result 中尚未存在的新记录(例如按 name 或 name+asset 组合去重),则需先读取并解析现有内容:

$filePath = "$dir/data"; $existingData = [];  // 尝试读取并解析已有数据(按行分割,提取 name 和 asset) if (file_exists($filePath)) {     $lines = array_filter(array_map('trim', file($filePath)));     foreach ($lines as $line) {         if (preg_match('/^([^,]+)s*,s*(.+)$/', $line, $matches)) {             $existingData[] = [                 'name'  => trim($matches[1]),                 'asset' => trim($matches[2])             ];         }     } }  // 构建去重后的待写入数据 $newLines = []; foreach ($result as $item) {     $name  = $item[0]['name'] ?? '';     $asset = $item[0]['asset'] ?? $item[0]['asset_no'] ?? '';      // 判断是否已存在(此处按 name + asset 联合去重)     $exists = false;     foreach ($existingData as $exist) {         if ($exist['name'] === $name && $exist['asset'] === $asset) {             $exists = true;             break;         }     }      if (!$exists) {         $newLines[] = "$name, $asset";     } }  // 追加新记录(仅新增部分) if (!empty($newLines)) {     file_put_contents($filePath, implode("rn", $newLines) . "rn", FILE_APPEND | LOCK_EX); }

✅ 优点:精准控制增量,兼容历史数据;
⚠️ 注意:LOCK_EX 可防止并发写入冲突;正则解析需适配实际数据格式;大规模数据建议改用数据库jsON 存储提升可维护性。

? 总结与最佳实践

  • 不要滥用 FILE_APPEND:它不解决“是否重复”问题,只解决“写在哪”的问题;
  • 明确业务语义:全量刷新 → 用覆盖写入;增量同步 → 先读后比再追加;
  • 健壮性增强:添加 is_writable() 检查、异常捕获、路径安全过滤(如避免 ../);
  • 进阶建议:长期项目中,推荐将结构化数据存为 json 文件(file_put_contents(…, json_encode($result))),便于序列化/反序列化与跨语言兼容。

通过合理选择写入策略并修正原始代码中的变量名错误($data → $asset)和键名兼容处理(asset / asset_no),即可彻底解决重复写入问题。

立即学习PHP免费学习笔记(深入)”;

text=ZqhQzanResources