php中array_unique()不能直接处理json字符串,须先json_decode()转数组;对对象数组需按字段(如id)去重,可用array_column()+array_unique()+array_filter()或array_reduce()实现。

PHP 中用 array_unique() 处理 JSON 数组去重,但得先解码
JSON 字符串本身是纯文本,不能直接去重;必须先用 json_decode() 转成 PHP 数组,再操作。常见错误是试图对 JSON 字符串调用 array_unique(),结果返回 null 或原样不变。
- 如果 JSON 是对象数组(如
[{"id":1},{"id":1}]),array_unique()默认按「字符串值」比较,会失效——因为两个对象转字符串都是Object,判为相同 - 若 JSON 是简单一维数组(如
[1,2,2,3]),array_unique($arr)可直接用,但注意它保留原始键名,需用array_values()重排索引 - 去重后别忘了用
json_encode()转回 JSON,否则前端收不到合法格式
处理对象数组重复:用 array_column() + array_unique() 提取唯一标识
多数业务场景的“重复”其实指某个字段(如 id、email)相同。直接对整个对象去重不可靠,应先抽取出关键字段做去重依据。
- 先
json_decode($json, true)得到关联数组 - 用
array_column($arr, 'id')提取所有id值,再array_unique()得唯一id列表 - 再用
array_filter()遍历原数组,只保留id在唯一列表中首次出现的项(避免多次in_array低效) - 示例片段:
$data = json_decode($json, true); $ids = array_column($data, 'id'); $unique_ids = array_unique($ids); $seen = []; $result = array_filter($data, function($item) use ($unique_ids, &$seen) { if (!in_array($item['id'], $unique_ids)) return false; if (isset($seen[$item['id']])) return false; $seen[$item['id']] = true; return true; });
用 array_reduce() 一行逻辑完成对象去重(PHP 7.4+ 更简洁)
比起多次遍历,用 array_reduce() 累积去重结果更高效,也更容易控制“保留第一个还是最后一个”。尤其适合字段不固定、需动态指定去重键的场景。
- 传入空数组作为初始值,每次检查当前项的去重键是否已存在,不存在则追加
- 注意:
array_reduce()不保留原始键名,结果是数字索引数组,符合多数 API 返回预期 - 示例(按
name去重):$data = json_decode($json, true); $unique = array_reduce($data, function($carry, $item) { $key = $item['name'] ?? ''; if (!isset($carry[$key])) { $carry[$key] = $item; } return $carry; }, []); $result = array_values($unique); // 去掉关联键,只留数值索引 - 兼容性提示:PHP ?? 操作符
JSON 去重失败的三个典型错误信号
不是代码没跑,而是结果不对——这些现象说明去重逻辑或数据结构理解有偏差:
立即学习“PHP免费学习笔记(深入)”;
-
json_decode()返回null:检查 JSON 格式是否合法(用json_last_error_msg()查错),常见于中文乱码、尾部逗号、单引号代替双引号 - 去重后数组长度没变:大概率是对象数组被当字符串处理了,确认是否用了第二个参数
true(否则返回对象,array_unique()无法处理) - 部分重复项还在:检查去重字段是否存在空值、大小写差异(如
"Email"和"email")、前后空格(需提前trim())
真正麻烦的不是语法,是搞不清“重复”的定义——是整行完全一样?还是某个字段一样?这个判断必须在写代码前就明确,否则后面全白调。











