array_unique无法处理多维数组,因其内部将子数组转为字符串后均为"Array",导致哈希冲突;需用serialize/json_encode标准化后再去重,或按指定键去重。

array_unique 只能对一维数组去重,因为它内部比较的是元素的字符串值(或整数值),而多维数组的每个子数组在转换为字符串时都变成类似 Array 的固定字符串,导致所有子数组“看起来一样”,自然无法区分。
为什么 array_unique 处理不了多维数组
PHP 的 array_unique 底层使用哈希表去重,依赖 == 比较。但 PHP 中两个数组用 == 判断相等,需满足:键名相同、对应值相等且顺序一致。问题在于:array_unique 并不直接用 ==,而是把每个元素先 strval() 再哈希 —— 而任何数组转成字符串都是 "Array",所以所有子数组哈希后都撞到同一个桶里,只保留第一个。
例如:
$multi = [[1,2], [3,4], [1,2]]; var_dump(array_unique($multi)); // 输出仍是全部三个,没去重手动实现多维数组去重(推荐:序列化 + 去重 + 反序列化)
核心思路:把每个子数组「标准化」为唯一可比的标量(如 JSON 字符串或序列化字符串),去重后再还原。
- 用
array_map('serialize', $arr)把每个子数组转成唯一字符串 - 用
array_unique对这些字符串去重 - 再用
array_map('unserialize', ...)还原回数组
完整函数示例:
function array_unique_multi($arr) { if (!$arr) return $arr; $serialized = array_map('serialize', $arr); $unique_serialized = array_unique($serialized); return array_map('unserialize', $unique_serialized); }更健壮的替代方案:用 JSON 编码(适合纯数值/字符串数据)
如果子数组不含资源、对象、闭包等不可 JSON 化的内容,用 json_encode 更安全(避免 unserialize 的潜在风险):
- 编码时加
JSON_SORT_KEYS和JSON_NUMERIC_CHECK,确保结构等价的数组生成相同字符串 - 注意:浮点数精度、null/0/'' 的类型差异可能影响结果,需按业务判断是否接受
按指定键去重(关联多维数组常见需求)
比如用户数组 [ ['id'=>1,'name'=>'A'], ['id'=>2,'name'=>'B'], ['id'=>1,'name'=>'C'] ],想按 'id' 去重(保留首次出现):
- 遍历原数组,用一个辅助数组记录已见过的
id - 遇到新
id才加入结果,跳过重复项
不复杂但容易忽略细节。关键在选对“可比标识”——序列化保结构、JSON 保可读、键去重保业务语义。

















