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

PHP写入JSON文件时数据丢失且从头重复的原因及解决

JSON文件追加数据丢失的原因及解决办法

问题原因

你的脚本出现数据丢失的核心原因是并发写入冲突。当多个请求同时访问这个脚本时,会出现以下时序问题:

  • 请求A读取api.json的旧数据
  • 请求B同时也读取到了同一版旧数据
  • 请求A把新数据追加后写入文件
  • 请求B基于之前读的旧数据追加新数据,然后写入文件,直接覆盖了请求A的修改结果
    这种情况下,最后完成写入的请求会覆盖之前所有的新增数据,导致中间的数据丢失。

另外你的代码里还有一个小语法问题:数组里的'talktime' : '2023-09-08 00:00:10'用了冒号,PHP数组键值对应该用=>,不过这个不是导致数据丢失的直接原因,但建议修正。

解决方案

方案1:添加文件锁机制

通过文件锁确保同一时间只有一个进程能读写JSON文件,避免并发冲突。修改后的代码如下:

$filePath = 'data/api.json';
// 以读写模式打开文件,文件不存在则创建
$fileHandle = fopen($filePath, 'c+');

if ($fileHandle) {
    // 获取独占锁,阻塞直到获取到锁
    if (flock($fileHandle, LOCK_EX)) {
        // 读取文件内容
        $currentContent = stream_get_contents($fileHandle);
        // 处理文件为空或JSON解析失败的情况,默认返回空数组
        $dataArray = json_decode($currentContent, true) ?: [];

        $newRecord = [
            'id' => $_GET['id'],
            'name' => 'SIMONE',
            'talktime' => date('Y-m-d H:i:s') // 建议用当前时间,而非固定值
        ];
        $dataArray[] = $newRecord;
        $finalContent = json_encode($dataArray, JSON_PRETTY_PRINT);

        // 将文件指针移到开头,截断原有内容,写入新数据
        ftruncate($fileHandle, 0);
        rewind($fileHandle);
        fwrite($fileHandle, $finalContent);

        // 释放锁
        flock($fileHandle, LOCK_UN);
        $message = "<label class='text-success'>File Appended Successfully</label>";
    } else {
        $message = "<label class='text-danger'>Failed to acquire file lock</label>";
    }
    fclose($fileHandle);
} else {
    $message = "<label class='text-danger'>Failed to open target file</label>";
}

关键说明:

  • 使用flock($handle, LOCK_EX)获取独占锁,确保同一时间只有一个进程能操作文件
  • 处理文件为空的情况,避免json_decode返回null导致后续数组追加报错
  • 用ftruncate和rewind组合覆盖原有文件内容,替代直接file_put_contents

方案2:改用数据库存储

如果你的应用并发量较高或者数据量持续增长,建议放弃用JSON文件存储数据,改用MySQL、SQLite等数据库。数据库本身具备事务、行锁等机制,能更可靠地处理并发写入场景,同时方便后续的数据查询、统计等操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:25:04