JSON新增数据ID无法递增且旧数据被覆盖的技术求助
问题排查与修复方案
我帮你分析了代码和JSON结构,找到了两个核心问题的根源,下面逐一说明并给出修复后的完整代码:
1. ID始终停留在0的原因
你当前获取最大ID的逻辑完全错误:
$maxID = max($database['data']); $ID = ++$maxID["id"];
$database['data']是包含多个关联数组的索引数组,max()函数在这里会把每个关联数组转换成字符串(比如Array)进行比较,最终只会返回数组的最后一个元素,而不是id值最大的元素。这就导致即使已有数据的id不为0,你也无法正确获取最大值,最终ID始终无法递增。
2. 新增数据时旧数据被覆盖的可能原因
- 文件名生成错误:你当前的
file字段没有正确赋值为生成的JSON文件名(比如jsonData_0.json),而是可能留空或使用了错误的值,导致新生成的文件覆盖了旧的空文件名文件; - 并发写入风险:如果多个请求同时操作JSON文件,未加锁的读写操作会导致后写入的内容覆盖之前的修改;
- 数组追加逻辑虽正确,但ID重复会导致后续修改操作覆盖同ID的数据。
修复后的完整代码
include_once('database_json.php'); $data = $_POST; $errors = array(); if (!empty($data)) { $newExerciseData = $data; $databaseFile = 'json_files/database.json'; // 加锁读取数据库文件,避免并发冲突 $handle = fopen($databaseFile, 'r'); flock($handle, LOCK_SH); $textContent = fread($handle, filesize($databaseFile)); flock($handle, LOCK_UN); fclose($handle); $database = json_decode($textContent, true); $database['data'] = $database['data'] ?? []; // 确保data字段始终是数组 if ($data['id'] === 'new') { // 正确生成递增ID if (empty($database['data'])) { $ID = 0; } else { $allIds = array_column($database['data'], 'id'); $maxId = max($allIds); $ID = $maxId + 1; } $newJsonFile = 'jsonData_' . $ID . '.json'; $newJsonFilePath = 'json_files/' . $newJsonFile; $newArrayData = array( 'id' => $ID, 'exercisetitle' => $newExerciseData['exercisetitle'] ?? '', 'exerciseWord' => $newExerciseData['exerciseWord'] ?? [], 'syllables' => $newExerciseData['syllables'] ?? [], 'file' => $newJsonFile, // 正确赋值文件名 'audio' => null, 'language' => null ); // 追加新数据到数组 $database['data'][] = $newArrayData; // 加锁写入数据库文件 $handle = fopen($databaseFile, 'w'); flock($handle, LOCK_EX); fwrite($handle, json_encode($database, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); flock($handle, LOCK_UN); fclose($handle); file_put_contents($newJsonFilePath, json_encode($newExerciseData, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); } else { $targetId = (int)$_POST['id']; $index = array_search($targetId, array_column($database['data'], 'id')); if ($index !== false) { $newJsonFile = 'jsonData_' . $targetId . '.json'; $newJsonFilePath = 'json_files/' . $newJsonFile; $newArrayData2 = array( 'id' => $targetId, 'exercisetitle' => $newExerciseData['exercisetitle'] ?? '', 'exerciseWord' => $newExerciseData['exerciseWord'] ?? [], 'syllables' => $newExerciseData['syllables'] ?? [], 'file' => $newJsonFile, 'audio' => null, 'language' => null ); $database['data'][$index] = $newArrayData2; $handle = fopen($databaseFile, 'w'); flock($handle, LOCK_EX); fwrite($handle, json_encode($database, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); flock($handle, LOCK_UN); fclose($handle); file_put_contents($newJsonFilePath, json_encode($newExerciseData, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); } else { $errors[] = "未找到ID为{$targetId}的数据"; } } if (!empty($errors)) { echo json_encode(['errors' => $errors], JSON_UNESCAPED_UNICODE); } else { echo json_encode($newExerciseData, JSON_UNESCAPED_UNICODE); } }
额外优化说明
- 文件锁机制:新增了文件读写锁,避免多请求并发操作时出现数据覆盖的问题;
- 字段默认值:给每个字段添加了默认值,防止POST数据缺失导致JSON结构异常;
- 数组安全处理:用
$database['data'] = $database['data'] ?? []确保data字段始终是数组,避免空文件或格式错误导致的报错; - 错误处理:新增了修改数据时未找到对应ID的错误提示,方便调试。
内容的提问来源于stack exchange,提问作者user9689724
相关产品推荐
相关产品推荐

