PHP脚本添加JSON对象去重后保持顺序的技术问题
解决PHP脚本添加JSON对象时的顺序保持问题
你的问题出在array_unique()和array_values()的组合上。array_unique()会保留每个元素第一次出现的实例,并且返回的数组会保留原数组的键名;随后的array_values()会把这些元素按键名升序重新排列,这就彻底打乱了你原本的添加顺序——哪怕你是把新数据追加到数组末尾,去重后也会被重新排序。
下面分两种场景给出解决方案:
情况1:允许重复对象,仅需保持添加顺序
如果你的业务场景允许同一个id或wallet_address的对象重复存在,那直接去掉去重的两行代码即可:
$accountData = json_decode(file_get_contents($filetxt_1), true); $newdata['id'] = $uvon; $newdata['wallet_address'] = $walletaddress; $newdata['timestamp'] = time(); $accountData[] = $newdata; // 移除去重逻辑,直接写入 file_put_contents($filetxt_1, json_encode($accountData, JSON_PRETTY_PRINT));
这样每次新对象都会被追加到数组末尾,完全保持添加顺序。
情况2:需要去重,但保留最后一次添加的顺序
如果必须去重(避免同一个对象重复存储),同时要让最后一次添加的对象排在数组末尾,那不能用array_unique(),得换一种去重逻辑:
$accountData = json_decode(file_get_contents($filetxt_1), true); $newdata['id'] = $uvon; $newdata['wallet_address'] = $walletaddress; $newdata['timestamp'] = time(); // 先把新数据追加到数组末尾 $accountData[] = $newdata; // 自定义去重逻辑:保留每个id最后一次出现的元素,维持添加顺序 $uniqueData = []; // 从后往前遍历,确保最新的元素先被记录 for ($i = count($accountData) - 1; $i >= 0; $i--) { $item = $accountData[$i]; // 用id作为唯一标识,避免重复存储 if (!isset($uniqueData[$item['id']])) { $uniqueData[$item['id']] = $item; } } // 反转数组,让最新添加的元素回到数组末尾 $array = array_reverse(array_values($uniqueData)); // 写入文件时添加锁,避免并发请求导致数据丢失 $fileHandle = fopen($filetxt_1, 'w'); flock($fileHandle, LOCK_EX); // 独占锁,防止其他进程写入 fwrite($fileHandle, json_encode($array, JSON_PRETTY_PRINT)); flock($fileHandle, LOCK_UN); // 释放锁 fclose($fileHandle);
这里的核心思路:
- 从后往前遍历数组,确保每个唯一
id只保留最后一次出现的实例; - 反转数组恢复“最新元素在末尾”的添加顺序;
- 加入文件锁机制,解决多并发请求下的文件写入冲突问题(这是文件存储数据的常见隐患)。
内容的提问来源于stack exchange,提问作者Charles Raiser
相关产品推荐
相关产品推荐

