最直接方法是array_unique(array_merge($a, $b));它合并后按值去重,保留首现键名,但默认松散比较("1"与1视为相同),数字键不重排,多维数组不支持,需类型严格时加sort_regular参数。

array_merge 后用 array_unique 去重最直接
PHP 中 array_merge 本身不处理重复,它只是把数组拼起来,键名重复时还会覆盖(数值键重排,字符串键后值覆盖前值)。所以合并后去重,得靠 array_unique。注意它默认只比较值,不区分类型("1" 和 1 被视为相同),且会保留第一个出现的键名——这点常被忽略。
实操建议:
- 对纯数值数组,直接
array_unique(array_merge($a, $b))即可 - 若需保持原始键名顺序(比如关联数组中 key 有意义),加第三个参数
SORT_REGULAR:array_unique(array_merge($a, $b), SORT_REGULAR) - 如果数组里有嵌套结构(如多维数组),
array_unique会失效(PHP 8.0+ 仍不支持递归去重),此时必须手动遍历 +serialize或自定义比较逻辑 - 去重后索引是乱的(字符串键保留,数字键不重排),需要重置数字索引就再套一层
array_values
合并前就去重能避免冗余计算
如果你控制得了输入源(比如两个数组来自不同查询但语义上不应有交集),提前去重更高效。尤其当数组很大时,array_merge + array_unique 是 O(n+m) 时间,但中间生成了一个更大的临时数组;而分别去重再合并,内存压力小,也更容易定位哪边带了脏数据。
常见错误现象:
- 合并后发现少了几个元素,其实是
array_unique把你没意识到的类型隐式转换给“吃掉”了(比如数据库取的int和 API 返回的stringID) - 用
array_unique($arr, SORT_STRING)想强制字符串比较,结果数值0和空字符串""又被当成一样——这时得自己写回调
PHP 7.4+ 可用 spl_object_id 配合 array_filter 去重对象数组
对象数组不能直接用 array_unique,它只比较 ==,不是 ===,且无法识别对象身份。正确做法是提取唯一标识,或借助对象 ID。
实操建议:
- 若对象有唯一字段(如
$obj->id),用array_column提取后配合array_keys+array_unique筛选原数组 - 若只是想剔除完全相同的对象引用(同一实例多次出现),可用
spl_object_id:$ids = [];<br>$filtered = array_filter($objects, function($obj) use (&$ids) {<br> $id = spl_object_id($obj);<br> if (in_array($id, $ids)) return false;<br> $ids[] = $id;<br> return true;<br>}); - 注意
spl_object_id在 PHP 7.4+ 才稳定,旧版本得用spl_object_hash,但它在对象销毁后可能复用,不够安全
用 array_diff_key 或自定义循环替代 array_unique 的场景
当你要去重但又必须保留某些特定键(比如只允许保留第一个数组里的 key,后续合并进来的同名 key 全丢),array_unique 就不够用了。这时候得换思路。
使用场景:
- 配置合并:主配置数组优先,扩展配置里同 key 的值一律忽略 → 用
array_merge($primary, array_diff_key($secondary, $primary)) - 需要按某种业务规则去重(比如时间戳最新者胜出),就得先
usort再遍历去重,不能依赖内置函数 - 大数组慎用
array_unique:它内部用哈希表实现,但 PHP 对哈希冲突处理较重,极端情况下性能跳变;此时分块处理 + 手动isset判重更可控
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











