PHP中array_unique()不能直接处理JSON字符串,须先json_decode()转数组;对对象数组需按字段(如id)去重,可用array_column()+array_unique()+array_filter()或array_reduce()实现。
PHP 中用
处理 JSON 数组去重,但得先解码
JSON 字符串本身是纯文本,不能直接去重;必须先用
转成 PHP 数组,再操作。常见错误是试图对 JSON 字符串调用
,结果返回
或原样不变。
如果 JSON 是对象数组(如
),
默认按「字符串值」比较,会失效——因为两个对象转字符串都是
,判为相同
若 JSON 是简单一维数组(如
),
可直接用,但注意它保留原始键名,需用
重排索引
去重后别忘了用
转回 JSON,否则前端收不到合法格式
处理对象数组重复:用
+
提取唯一标识
多数业务场景的“重复”其实指某个字段(如
、
)相同。直接对整个对象去重不可靠,应先抽取出关键字段做去重依据。
先
得到关联数组
用
提取所有
值,再
得唯一
列表
再用
遍历原数组,只保留
在唯一列表中首次出现的项(避免多次
低效)
示例片段:
用
一行逻辑完成对象去重(PHP 7.4+ 更简洁)
比起多次遍历,用
累积去重结果更高效,也更容易控制“保留第一个还是最后一个”。尤其适合字段不固定、需动态指定去重键的场景。
传入空数组作为初始值,每次检查当前项的去重键是否已存在,不存在则追加
注意:
不保留原始键名,结果是数字索引数组,符合多数 API 返回预期
示例(按
去重):
兼容性提示:PHP ?? 操作符
JSON 去重失败的三个典型错误信号
不是代码没跑,而是结果不对——这些现象说明去重逻辑或数据结构理解有偏差:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
立即学习
“
PHP免费学习笔记(深入)
”;
返回
:检查 JSON 格式是否合法(用
查错),常见于中文乱码、尾部逗号、单引号代替双引号
去重后数组长度没变:大概率是对象数组被当字符串处理了,确认是否用了第二个参数
(否则返回对象,
无法处理)
部分重复项还在:检查去重字段是否存在空值、大小写差异(如
和
)、前后空格(需提前
)
真正麻烦的不是语法,是搞不清“重复”的定义——是整行完全一样?还是某个字段一样?这个判断必须在写代码前就明确,否则后面全白调。
array_unique()json_decode()array_unique()null[{"id":1},{"id":1}]array_unique()Object[1,2,2,3]array_unique($arr)array_values()json_encode()array_column()array_unique()idemailjson_decode($json, true)array_column($arr, 'id')idarray_unique()idarray_filter()idin_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()array_reduce()array_reduce()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); // 去掉关联键,只留数值索引json_decode()nulljson_last_error_msg()truearray_unique()"Email""email"trim()