array_uintersect不直接支持二维数组去重,需通过json_encode或提取键值等方法将子数组转为可比较标量,在回调中实现按内容或指定字段的交集匹配。

array_uintersect 本身不直接支持二维数组去重,它只适用于一维数组的交集比较,且要求传入的每个数组都是一维的。但你可以通过“把二维数组转成可比较的一维结构”+自定义回调函数的方式,间接实现按某字段或整体内容去重的效果。
核心思路:把二维元素映射为可哈希/可比较的标量
PHP 的 array_uintersect 比较的是数组的「值」,而二维数组的值是数组(不可直接比较)。所以必须在回调函数中,将每个子数组转换成一个能唯一代表它的字符串或数字(比如 JSON 编码、拼接关键字段、序列化等),再做比较。
方法一:用 json_encode 做全量内容去重(最简单)
适合需要完全相同的二维结构才视为重复的场景:
- 把所有二维数组先用 json_encode($item) 转成字符串
- 传给 array_uintersect 的回调函数,对两个编码后的字符串做 strcmp
- 注意:要保证键顺序一致(PHP 8.0+ 的 json_encode 默认保持关联键序,安全)
示例:
$a = [['id'=>1, 'name'=>'Alice'], ['id'=>2, 'name'=>'Bob']];<br>$b = [['id'=>1, 'name'=>'Alice'], ['id'=>3, 'name'=>'Charlie']];<br><br>$result = array_uintersect($a, $b, function($x, $y) {<br> return strcmp(json_encode($x), json_encode($y));<br>});<br>// 结果:[['id'=>1, 'name'=>'Alice']]
方法二:按指定键去重(更常用、更可控)
比如只看 'id' 字段是否重复,忽略其他差异:
- 回调中提取 $x['id'] 和 $y['id'],直接比较(需确保键存在)
- 推荐加空值判断,避免 Notice
- 若要多字段联合去重(如 id + type),可拼接:$x['id'].'|'.$x['type']
示例(按 id 去重):
$a = [['id'=>1, 'name'=>'Alice'], ['id'=>2, 'name'=>'Bob']];<br>$b = [['id'=>1, 'name'=>'Alicia'], ['id'=>3, 'name'=>'Charlie']];<br><br>$result = array_uintersect($a, $b, function($x, $y) {<br> $x_id = $x['id'] ?? null;<br> $y_id = $y['id'] ?? null;<br> return $x_id $y_id; // PHP 7+ 强势飞船操作符<br>});<br>// 结果:[['id'=>1, 'name'=>'Alice']](保留 $a 中第一个匹配项)
注意事项与避坑点
- array_uintersect 返回的是第一个数组中的原始元素,不是键对齐的结果 —— 它只按值匹配,保留 $a 中对应位置的完整子数组
- 回调函数必须返回整数: 0 表示大于,0 表示相等;别用 == 或 === 直接返回布尔
- 如果二维数组里有浮点、null、对象或资源,json_encode 可能失真,此时改用 serialize() 更稳妥(但结果不可读)
- 真要去重(而非求交集),更推荐用 array_unique($arr, SORT_REGULAR) + 自定义封装,或用循环 + hash 缓存,语义更清晰
不复杂但容易忽略:array_uintersect 是「求交集」,不是「去重」。你要的是去重,本质是「保留首次出现、跳过后续重复」,那更适合用 array_reduce 或 foreach 配合 in_array / isset(缓存键) 实现。用 array_uintersect 是取巧,仅当已有多个数组想快速找共同子集时才自然适用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











