array_udiff不支持直接比较多维数组,需通过自定义回调实现子数组相等判断,常见方法有serialize比较、按指定键(如id)比较或递归深度比较,且回调必须返回全序结果(-1/0/1)。

array_udiff 本身不支持直接比较多维数组,它只适用于一维数组的元素差异计算。当你传入多维数组(比如包含子数组的数组)时,PHP 会把每个子数组当作一个整体来传递给回调函数 —— 但默认情况下,PHP 无法直接用 == 或 === 比较两个数组,所以必须在自定义回调中手动实现“两个子数组是否相等”的逻辑。
核心要点:回调函数必须能比较数组结构
array_udiff 的回调函数接收两个参数($a 和 $b),需返回整数:
- 返回 0 表示两者“相等”(即视为重复,不保留在结果中)
- 返回 < 0 表示 $a 小于 $b(排序/判定依据,不影响差异逻辑,但必须有明确顺序)
- 返回 > 0 表示 $a 大于 $b
关键在于:你要自己定义“两个子数组什么时候算相同”。常见策略是序列化后比较、或逐键递归比较、或只比特定键(如 id)。
方法一:用 serialize() 快速判断数组完全一致
适合结构固定、且不关心键顺序但要求内容完全相同的场景(注意:serialize 对键顺序敏感,关联数组键序不同会导致结果不同):
立即学习“PHP免费学习笔记(深入)”;
$arr1 = [['id'=>1, 'name'=>'Alice'], ['id'=>2, 'name'=>'Bob']];
$arr2 = [['id'=>2, 'name'=>'Bob'], ['id'=>3, 'name'=>'Charlie']];
$result = array_udiff($arr1, $arr2, function($a, $b) {
return strcmp(serialize($a), serialize($b));
});
// $result = [['id'=>1, 'name'=>'Alice']](因为 [2,'Bob'] 在两者中都存在)
方法二:按指定键(如 id)比较,更实用
多数业务中,你只关心某个唯一标识字段(如 id、uuid)。这时回调只需比该键值,简洁高效且不受数组其他字段干扰:
$result = array_udiff($arr1, $arr2, function($a, $b) {
$idA = $a['id'] ?? null;
$idB = $b['id'] ?? null;
if ($idA == $idB) return 0;
return ($idA < $idB) ? -1 : 1;
});
这样,只要两个子数组的 'id' 相同,就认为它们是同一个元素,会被当作“重复”剔除。
方法三:递归键值比较(兼容键序无关)
若需真正语义相等(忽略键顺序、支持嵌套),可写一个安全的递归比较函数,但要注意性能和循环引用风险:
function arraysEqual($a, $b) {
if (is_array($a) !== is_array($b)) return false;
if (count($a) !== count($b)) return false;
foreach ($a as $k => $v) {
if (!array_key_exists($k, $b)) return false;
if (is_array($v) && is_array($b[$k])) {
if (!arraysEqual($v, $b[$k])) return false;
} elseif ($v !== $b[$k]) {
return false;
}
}
return true;
}
$result = array_udiff($arr1, $arr2, function($a, $b) {
return arraysEqual($a, $b) ? 0 : 1; // 注意:仅返回 0/1 不满足“全序”,建议补全
});
// 实际使用时,仍需让回调返回 -1/0/1 全序结果,不能只返回 0/1
注意事项
- 回调必须返回全序结果:不能只判断相等,还要能表达大小关系(哪怕只是约定规则,如按 JSON 编码字典序)
-
array_udiff 只比较第一个数组对后续数组的差集:即
array_udiff($a, $b, $c)是 “在 $a 中但不在 $b 且不在 $c 中的元素” - 多维数组元素若含资源、对象或闭包,serialize 会失败,需提前过滤或换策略
- 性能敏感场景慎用 serialize 或深度递归,优先考虑基于主键的轻量比较
不复杂但容易忽略的是:回调函数的设计目标不是“判等”,而是提供一个可排序的比较依据 —— 差异计算是基于这个排序隐式完成的。只要逻辑自洽,就能正确提取差集。



















