array_diff 失效是因为其内部将子数组强制转为字符串“array”,导致所有子数组被误判为相同;正确方案包括array_udiff+自定义比较、递归函数或第三方深度比较库。

array_diff 只支持一维数组比较,遇到多维数组会把子数组当作 Array 字符串来比对,所有子数组都变成相同字符串 "Array",结果自然全被当成“重复”而过滤掉,最终返回空数组。
为什么多维数组用 array_diff 会失效
PHP 的 array_diff 内部使用字符串强制转换((string)$value)来判断元素是否相等。对于数组类型,PHP 转换结果恒为字符串 "Array",所以:
-
[1,2]→"Array" -
['a'=>'x']→"Array" -
[[1],[2]]→ 两个子数组都转成"Array",被判定为“相同”
这就导致它根本无法区分不同结构、不同内容的子数组,逻辑上就不可用。
正确对比多维数组差异的替代方案
需改用能递归或深度比较的函数:
- array_udiff + 自定义比较函数:用 json_encode 或 serialize 将子数组转为唯一字符串再比较(注意键顺序、浮点精度、对象等问题)
- 自定义递归 diff 函数:逐层遍历键和值,对数组类型递归调用,对非数组用 === 判断
- 第三方库如 symfony/var-exporter 或 deep-diff 类工具(适合复杂场景)
一个轻量可用的递归 diff 示例
以下函数可处理含数字/字符串/子数组的嵌套结构:
(仅作示意,生产环境建议加类型检查和错误处理)function array_diff_recursive($arr1, $arr2) {
$result = [];
foreach ($arr1 as $key => $value) {
if (!array_key_exists($key, $arr2)) {
$result[$key] = $value;
} elseif (is_array($value) && is_array($arr2[$key])) {
$diff = array_diff_recursive($value, $arr2[$key]);
if (!empty($diff)) $result[$key] = $diff;
} elseif ($value !== $arr2[$key]) {
$result[$key] = $value;
}
}
return $result;
}
简单场景下的快速 workaround
如果只是想“找出哪些子数组在 $a 中有、但在 $b 中没有”,且子数组结构扁平、键固定,可先用 array_map('serialize', $arr) 转成一维字符串数组,再用 array_diff,最后 array_map('unserialize', ...) 还原:
- 优点:写法简单,适合临时脚本
- 缺点:不兼容含资源、闭包、部分对象;序列化格式敏感(如键顺序影响结果)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











