php 8.0 的 array_diff_assoc 不支持二维数组去重,因其仅做一维键值严格比较,遇子数组会触发 notice 且无法递归比较;推荐用 serialize + array_unique 或 json_encode + array_unique 实现。

PHP 8.0 中 array_diff_assoc 本身**不支持直接处理二维数组去重**,因为它只做「一维键值对」的严格比较(包括键名和值),遇到子数组时会将整个数组视为不可比较的类型(触发 notice 并视作不相等),无法按你期望的方式“对比二维结构并去重”。想实现二维数组去重,需换思路——不能依赖 array_diff_assoc 单独完成,而要配合序列化、自定义比较或转换为可比形式。
为什么 array_diff_assoc 对二维数组无效
array_diff_assoc 要求值能用 == 和 === 安全比较。PHP 中两个数组即使内容相同,=== 也返回 false(除非是同一引用)。所以:
- 传入含子数组的二维数组,函数内部比较会失败或返回意外结果;
- 官方文档明确说明:该函数「不递归比较数组值」;
- 实际运行可能报
Notice: Array to string conversion,且去重结果不可靠。
推荐方案:用 serialize + array_unique 实现二维去重
最常用、简洁且兼容 PHP 8.0 的方式是先将每行子数组序列化为唯一字符串,去重后再反序列化:
$arr = [
['id' => 1, 'name' => 'Alice'],
['id' => 2, 'name' => 'Bob'],
['id' => 1, 'name' => 'Alice'], // 重复项
];
// 序列化 → 去重 → 反序列化
$serialized = array_map('serialize', $arr);
$unique_serialized = array_unique($serialized);
$result = array_map('unserialize', $unique_serialized);
// $result 就是去重后的二维数组(保持原始顺序)
✅ 优点:代码短、逻辑清晰、保留键名和顺序;⚠️ 注意:确保子数组中不含资源、闭包等不可序列化内容。
进阶方案:用 array\_usort + 自定义比较做「精准去重」
若需按特定字段(如只看 id)去重,或要保留「首次出现」的完整行,可用 array_reduce 或循环 + 键映射:
$seen = [];
$result = [];
foreach ($arr as $item) {
$key = $item['id'] ?? spl_object_hash((object)$item); // 防空 key
if (!isset($seen[$key])) {
$seen[$key] = true;
$result[] = $item;
}
}
这种写法灵活可控,适合业务逻辑强的场景(比如仅根据 ID 去重,忽略 name 差异)。
替代函数:PHP 8.0+ 可考虑 json_encode(更安全)
相比 serialize,json_encode 更轻量、无执行风险,且对纯数据数组足够稳定:
$jsons = array_map('json_encode', $arr);
$unique_jsons = array_unique($jsons);
$result = array_map('json_decode', $unique_jsons);
// 若需关联数组,加第二个参数 true:json_decode($j, true)
✅ 适合不含资源、资源句柄、对象方法的纯数据二维数组;❌ 不支持 NaN、Inf、某些 Unicode 边界情况(但日常够用)。
不复杂但容易忽略:二维数组去重本质是「定义什么是重复」——是整行完全一致?还是某几个字段一致?选对方法前,先明确你的去重语义。PHP 8.0 没给开箱即用的二维 array_diff_assoc,但用好 serialize 或 json_encode 配合 array_unique,就能稳稳搞定。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











