php 7.4 的 array_diff 不支持多维数组比较,因其内部字符串转换使所有子数组变为"array"导致误判;推荐用 array_udiff 配合 serialize 比较、扁平化提取标识、递归标准化或第三方库如 spatie/array-functions 实现深度差异检测。

PHP 7.4 的 array_diff 确实只支持一维数组的值对比,遇到多维数组(比如包含子数组、对象或嵌套结构)会直接报错或返回空结果——因为它内部用字符串强制转换做比较,而数组转字符串是 "Array",所有多维元素都变成相同字符串,自然“全相等”。
用 array_udiff + 自定义比较函数替代
这是最标准、最可控的方式。利用 array_udiff 允许传入回调函数的特点,手动定义“两个子数组是否相等”的逻辑:
- 回调函数接收两个参数(即待比较的两个子数组),需返回整数:0 表示相等,负数表示前者小,正数表示前者大
- 推荐用
serialize($a) === serialize($b)判断完全一致(含键名、顺序、类型);若只需内容一致(忽略键顺序),可用ksort预处理再序列化 - 注意:
serialize对含资源或闭包的数组会失败,生产环境建议先用is_array和is_scalar做安全校验
$diff = array_udiff($arr1, $arr2, function($a, $b) {<br> return serialize($a) serialize($b);<br>});
先扁平化再 diff(适合结构固定场景)
如果多维数组其实是“记录列表”(如一组关联数组,每项有相同字段),可提取关键字段拼成唯一标识符,转为一维后对比:
- 用
array_map提取每项的id、name等组合成字符串(如$item['id'] . '|' . $item['name']) - 对生成的一维标识数组调用原生
array_diff,再通过标识反查原始数据 - 优点是性能好、不依赖序列化;缺点是需人工定义“差异维度”,无法捕获未参与拼接的字段变化
递归转成可比格式(兼容复杂嵌套)
对任意深度数组,可先用递归函数将其标准化为可排序/可哈希的结构(如规范键序 + 类型显式标记),再序列化对比:
- 写一个
normalizeArray函数:对每个子数组调用ksort,对数值强制类型转换(如(string)$val),跳过不可序列化项 - 将两个待比数组分别 normalize 后,再用
array_udiff+serialize对比 - 适合需要精确对比嵌套结构的场景,但要注意浮点精度、NaN 处理等边界情况
第三方库辅助(快速上线选型)
如果项目允许引入依赖,symfony/var-exporter 或 deep-diff 类库提供更鲁棒的深度数组比较能力:
-
symfony/var-exporter的Exporter可生成稳定字符串表示,比原生serialize更少受对象状态影响 - 轻量方案可用
spatie/array-functions,它封装了arrayDiffRecursive方法,底层已处理键序、类型、空值等细节 - 注意评估依赖体积和 PHP 版本兼容性(PHP 7.4 下优先选无 JIT 依赖的库)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











