array_unique返回全新数组且不修改原数组,键名保留但可能不连续,无法处理多维数组或对象,需手动实现嵌套去重逻辑。

array_unique 返回的是新数组,不是引用修改
array_unique() 永远不会改动原始数组,它总是返回一个**全新数组**。这意味着你必须显式赋值才能拿到结果:$unique = array_unique($arr);,否则原始变量 $arr 保持不变。
常见错误是写成 array_unique($arr); 后直接用 $arr,结果发现没去重——其实只是忘了接返回值。
键名保留但不连续,遍历时容易出错
去重后键名照搬原数组,但重复项被删掉,导致键名出现“空洞”。比如 [0 => 'a', 1 => 'b', 2 => 'a'] 经 array_unique() 后变成 [0 => 'a', 1 => 'b'];但如果原数组是 [3 => 'a', 5 => 'b', 7 => 'a'],结果就是 [3 => 'a', 5 => 'b']。
这种非连续键在以下场景会出问题:
- 用
for ($i = 0; $i 遍历(跳过缺失索引) - 用
isset($arr[$i])判断存在性($i=4时返回 false) - JSON 编码后变成对象而非数组(PHP 关联键触发 JSON 对象转换)
需要连续数字索引时,必须套一层 array_values(array_unique($arr))。
值比较按字符串松散规则,1 和 "1" 被当成相同
array_unique() 内部把所有值转为字符串再比对,所以 1、"1"、1.0 全算重复。这不是 bug,是设计行为。
如果你需要严格区分类型(比如 API 返回的整数 ID 和字符串 ID 必须共存),不能直接用 array_unique():
- 改用
array_reduce()+ 手动哈希判断 - 或先序列化:
array_unique(array_map('serialize', $arr)),再反序列化(注意安全性) - PHP 8.3+ 可考虑
array_unique($arr, SORT_FLAG_CASE | SORT_STRING)控制部分行为,但无法绕过类型转换本质
多维数组直接传入会报 Warning 并返回空数组
array_unique() 原生不支持多维数组。传入类似 [['id'=>1], ['id'=>2], ['id'=>1]] 会触发 Warning: array_unique(): Array to string conversion,且返回 NULL 或意外结果(取决于 PHP 版本)。
真要处理多维去重,得自己写逻辑:
- 按某个字段去重:用
foreach遍历 +in_array($item['field'], $seen)记录已见值 - 全量结构去重:先
array_map('serialize', $arr)转字符串,去重后再array_map('unserialize', ...) - 注意:序列化有安全风险,仅用于可信数据
别指望加个参数就能让 array_unique() 自动理解嵌套结构——它连对象都处理不了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











