array_unique默认松散比较导致"1"和1被当作相同值,需用sort_regular强制严格比较;它保留首个键、不重排索引,大数组性能差,应结合isset($seen[$v])手动去重。

array_unique 为什么去不掉字符串数字的重复?
因为 array_unique 默认用松散比较(==),"1" 和 1 被当成相同值。这不是 bug,是设计如此——它本就按 PHP 的类型转换规则判重。
常见错误现象:
输入 [1, "1", 2, "2"],结果只剩 [1, 2],字符串全被“吃掉”了。
- 加参数
SORT_REGULAR强制严格比较:array_unique($arr, SORT_REGULAR) - 如果数组全是字符串,且想保留原始键名,别忘了后续用
array_values()重排索引(array_unique不会自动重置键) -
SORT_STRING适合纯字符串数组,按字典序排后再去重,但键名仍保留原样
关联数组去重只看 value,key 怎么保?
array_unique 天然保留第一个出现的 key,丢弃后续重复 value 对应的 key。这点容易被误以为“随机丢”,其实是确定性行为:遍历顺序决定谁留下。
使用场景:比如处理 API 返回的用户列表,["id" => 123, "name" => "a"] 和 ["id" => 456, "name" => "a"] 共享相同 name,你想按 name 去重并保留首个用户。
立即学习“PHP免费学习笔记(深入)”;
- 直接用
array_unique($users, SORT_REGULAR)不行——它比整个子数组,不是单字段 - 得先提取目标字段成一维数组:
$names = array_column($users, 'name') - 再用
array_keys(array_unique($names))拿到要保留的原始键,最后array_intersect_key($users, ...)
大数组用 array_unique 很慢?替代方案有哪些
时间复杂度接近 O(n²),尤其开启 SORT_* 参数时会额外排序;10 万条以上数据明显卡顿。
性能影响:默认不排序最快,但松散比较不可控;加 SORT_REGULAR 后多一次内部排序,内存占用翻倍。
- 若只要去重不要键映射,用
array_flip(array_flip($arr))(仅限纯值,且会丢键) - 若需严格比较 + 保持键,手写循环 +
in_array($v, $seen, true)更可控,但注意in_array在大数组里也慢 - 真正大数据量(如导出清洗),改用
foreach配合isset($seen[$v])——利用 hash 表 O(1) 查找,前提是 $v 可作数组 key(即必须是标量或 null)
PHP 8.1+ 有更安全的替代函数吗?
没有新函数替代 array_unique,但 PHP 8.1 引入了 array_is_list 等辅助判断,对去重本身没直接帮助。
兼容性注意点:SORT_FLAG_CASE 只在 SORT_STRING 下生效,单独用无效;
PHP 7.2+ 才支持 SORT_NATURAL,老版本会警告。
- 跨版本安全写法:显式传
SORT_REGULAR,不依赖默认行为 - 别把对象数组直接喂给
array_unique——对象永远不相等,结果等于原数组,还触发 __toString 调用(如果定义了) - 含 NaN 或 resource 的数组,
array_unique行为未定义,提前过滤掉











