array_diff 比较值而非键,仅保留第一个数组中未在任何后续数组出现的元素,松散比较,不支持嵌套数组或对象,多数组时顺序影响结果,性能为 O(n×m)。

array_diff 比较的是值,不是键
它只看元素的值是否相等,完全忽略键名。哪怕两个数组键名一模一样,只要某个值在第二个数组里存在,就会被剔除。比如 array_diff(['a' => 1, 'b' => 2], [2]) 返回 ['a' => 1],因为 2 被删了,'b' 这个键根本没参与判断。
常见错误是以为它能“按键对齐比较”,结果发现键保留得乱七八糟,其实只是原样输出第一个数组中“值未在后续数组出现”的那些项。
- 所有参数都必须是数组,传字符串或
null会触发 warning - 比较时会做松散比较(
==),"1"和1被认为相等 - 如果要严格比较(
===),得用array_diff_assoc或自己写回调
多个数组一起比,顺序决定结果方向
array_diff 第一个参数是“基准数组”,后面所有参数都是“要排除的值来源”。结果永远只包含第一个数组里的元素,且仅当该值**不在任何后续数组中出现过**才保留。
比如 array_diff([1,2,3], [2], [3,4]) 返回 [1] —— 因为 2 在第二个数组里有,3 在第三个数组里有,只有 1 全程没出现过。
立即学习“PHP免费学习笔记(深入)”;
- 调换顺序:
array_diff([2], [1,2,3])返回空数组,因为2确实在第二个数组里 - 后续数组之间不互相比,只用来筛第一个数组
- 后续数组可以是任意数量,不限于两个
遇到嵌套数组或对象直接失效
array_diff 不递归,也不支持对象。如果数组里有子数组,比如 [1, [2,3]],和 [[2,3]] 做差,结果不会去掉那个子数组——PHP 把整个子数组当作不可比较的单元,松散比较下直接判定不等,所以它会被保留下来,但这是错觉,不是你想要的“结构差异”。
同理,对象实例之间永远不相等(除非是同一个引用),所以 array_diff 对含对象的数组基本没用。
- 真要比较嵌套结构,得用
array_udiff配自定义回调 - 简单场景可先
json_encode扁平化再比,但要注意浮点精度、键序、空格等副作用 - 别指望它处理
stdClass或DateTime实例
性能注意:大数组 + 字符串值容易慢
内部实现是逐个遍历第一个数组,对每个值再遍历所有后续数组做查找。最坏情况时间复杂度是 O(n×m),n 是第一个数组长度,m 是后续数组总长度。如果都是短整数,还好;但要是长字符串(比如 JSON 片段、HTML 片段),每次比较开销就上去了。
- 提前用
array_values重置键,避免稀疏数组拖慢遍历 - 如果后续数组很大且固定,建议先
array_flip变成键值对,再用isset查——但这就不是array_diff了,得自己写循环 - PHP 8.1+ 的
array_key_first等新函数帮不上忙,它不涉及键操作
真正复杂的差异需求,别硬套 array_diff,容易绕进性能坑里还逻辑错乱。



















