array_unique() 最直接但需注意键名不重排、不支持嵌套数组/对象、区分大小写;含业务字段去重要自定义逻辑,大数组需考虑性能,JSON 数据须先解码再处理。

用 array_unique() 最直接,但要注意键名保留规则
PHP 自带的 array_unique() 就是干这事的,它会遍历数组,去掉重复值,只留第一次出现的那个。但默认行为容易被忽略:它**不重排键名**,返回的仍是关联数组,数字键可能不连续。
常见错误现象:foreach 时以为键是 0/1/2,结果拿到的是 0/2/5;或者用 array_values() 前忘了重索引,导致 JSON 编码成对象而非数组。
- 如果原数组是索引数组且需要连续数字键,后面必须跟
array_values() - 如果含嵌套数组或对象,
array_unique()会直接报 Warning —— 它只支持标量和null - 区分大小写:字符串
"ABC"和"abc"被视为不同值
$arr = ['a', 'b', 'a', 'c']; $result = array_values(array_unique($arr)); // [0=>'a', 1=>'b', 2=>'c']
需要按特定字段去重?得自己写循环或用 array_reduce()
比如处理用户数据,想按 email 字段找唯一记录,array_unique() 没法直接用 —— 它不能指定比较维度。
这时常见做法是遍历 + 标记已见值,或用 array_reduce() 累积唯一项。关键点在于:用什么做“指纹”来判断重复。
- 推荐用
$seen[$item['email']]当哈希表,比in_array()查找快得多(O(1) vs O(n)) - 注意空值或缺失键:
$item['email'] ?? ''避免 Notice - 如果字段值本身含数组或对象,需先
json_encode()或serialize()再当键,否则报错
$users = [['id'=>1, 'email'=>'a@b.com'], ['id'=>2, 'email'=>'a@b.com']];
$unique = [];
$seen = [];
foreach ($users as $u) {
$key = $u['email'] ?? '';
if (!isset($seen[$key])) {
$seen[$key] = true;
$unique[] = $u;
}
}
性能敏感场景别用 array_unique() 处理大数组
官方函数底层是 C 实现,看似快,但它内部做了完整遍历+哈希比对,且会复制整个数组。当数组超 10 万项、值又很长(如 JSON 字符串)时,内存和时间开销明显上升。
真实瓶颈常在字符串哈希计算和内存分配,而不是逻辑本身。
- 若只需判断“是否存在重复”,用
count($arr) !== count(array_unique($arr))效率极低,改用array_flip()+count()更快 - 若后续还要按某字段排序,建议在去重循环里一并做,避免多遍遍历
- PHP 8.1+ 可考虑
array_key_first()配合引用优化,但收益有限,优先优化算法逻辑
JSON 数据去重时,先解码再处理,别在字符串层面操作
有人把 JSON 字符串当普通文本用 str_replace() 或正则去重,这非常危险 —— 字段顺序、空格、转义字符都会导致误判或破坏结构。
正确路径永远是:JSON → 数组 → 去重 → JSON。哪怕多一次 json_decode(),也比字符串操作可靠。
-
json_decode($json, true)必须加true,否则返回对象,array_unique()不认 - 解码失败时
json_last_error()一定要检查,空字符串或 null 会导致静默失败 - 如果原始 JSON 含深度嵌套且需按深层字段(如
data.user.id)去重,提前用递归提取字段值更稳妥
实际项目里,90% 的“找唯一值”需求靠 array_unique() + array_values() 就能解决。真正难的是定义清楚“什么是重复”——是全等比较?忽略大小写?还是按业务字段语义去重。这个边界没理清,代码写得再漂亮也白搭。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











