← PHP中的current():获取数组当前指针指向的元素 PHP中的array_diff():只比较值的数组差集 →

PHP中的array_diff_assoc():带键名比较的数组差集

原创 2026-05-22 PHP 已有人查阅

array_diff()只比较数组的值,不关心键名。但有时候你需要严格一点——键名和值都要匹配才算相同。

array_diff_assoc()就是干这个的:比较两个或更多数组的键名和值,返回在第一个数组中存在、但在其他数组中不存在的条目(键名+值都算在内)。

语法格式

array_diff_assoc(array $array1, array $array2 [, array $... ]): array

参数说明:

参数 说明 必填?
array1 要比较的原始数组 必填
array2 用来对比的数组 必填
array3... 更多用来对比的数组 可选

返回值: 返回一个数组,包含所有在array1中存在但不在其他数组中的键值对。

和array_diff的区别

函数 比较内容 使用场景
array_diff() 只看值 不关心键名,只统计哪些值没出现
array_diff_assoc() 键名+值都看 需要严格区分键名不同的情况

示例1:基础用法

<?php
$intory1 = [
    "sku001" => "键盘",
    "sku002" => "鼠标",
    "sku003" => "显示器",
    "sku004" => "耳机"
];

$intory2 = [
    "sku001" => "键盘",
    "sku002" => "鼠标",
    "sku005" => "摄像头"
];

$diff = array_diff_assoc($intory1, $intory2);
print_r($diff);
?>

输出:

Array
(
    [sku003] => 显示器
    [sku004] => 耳机
)

注意:虽然intory1里的"键盘"和"鼠标"的值在intory2里也存在,但键名匹配上了(sku001和sku002都一致),所以没有被列入差集。而"显示器"和"耳机"在intory2里没有对应的键名+值,所以返回。

示例2:键名相同但值不同

<?php
$student_scores_1 = [
    "code001" => 85,
    "code002" => 92,
    "code003" => 78
];

$student_scores_2 = [
    "code001" => 85,
    "code002" => 88,   // 值不同
    "code003" => 78
];

$diff = array_diff_assoc($student_scores_1, $student_scores_2);
print_r($diff);
?>

输出:

Array
(
    [code002] => 92
)

code002在两个数组中的值不同(92 vs 88),所以被算作差集返回。

示例3:键名不同但值相同

<?php
$fruit_basket_a = [
    "a1" => "苹果",
    "a2" => "香蕉",
    "a3" => "橙子"
];

$fruit_basket_b = [
    "b1" => "苹果",
    "b2" => "橙子",
    "b3" => "香蕉"
];

$diff = array_diff_assoc($fruit_basket_a, $fruit_basket_b);
print_r($diff);
?>

输出:

Array
(
    [a1] => 苹果
    [a2] => 香蕉
    [a3] => 橙子
)

惊讶吗?三个元素全返回了。虽然值都在第二个数组里存在,但键名不一样。array_diff_assoc要求键名和值同时相等才算匹配。这里a1和b1键名不同,所以不匹配。

个人经验分享

  1. 什么时候用array_diff_assoc而不是array_diff?

    • 处理关联数组,键名有实际意义(比如用户ID、商品编码)

    • 需要严格区分相同值的不同键名

    • 同步两个配置数组时,想找出具体哪个配置项变了

  2. 实际场景:对比配置变更

    $old_config = ["db_host" => "localhost", "db_name" => "old_db", "cache" => "redis"];
    $new_config = ["db_host" => "localhost", "db_name" => "new_db", "cache" => "redis"];
    $changes = array_diff_assoc($new_config, $old_config);
    // 返回 ["db_name" => "new_db"],只有变更的项
  3. 多维数组的限制
    array_diff_assoc()处理多维数组时,只能比较第一层。嵌套的子数组会被整体当作一个元素比较,不会递归比较内部。需要递归比较的话,自己写递归函数或者用array_udiff_assoc()配合自定义回调。

  4. 性能考虑
    这个函数比较的是两个数组的差值,时间复杂度大致是O(n*m)。两个数组都很大的时候(比如各几万条),运行时间会明显增加。大数据量下考虑用数据库操作或者算法优化。

示例4:多个数组比较

<?php
$team_a = ["id1" => "张伟", "id2" => "李芳", "id3" => "王磊", "id4" => "赵敏"];
$team_b = ["id1" => "张伟", "id2" => "刘强"];
$team_c = ["id3" => "王磊", "id5" => "陈晨"];

$unique_to_a = array_diff_assoc($team_a, $team_b, $team_c);
print_r($unique_to_a);
?>

输出:

Array
(
    [id4] => 赵敏
)

只有在team_a中存在,且在team_b和team_c中都不存在的条目才会返回。id1虽然值匹配,但键名也匹配上了所以排除;id3的值在team_c中出现了,键名也匹配上了所以排除;只有id4是独有的。

示例5:代码号学习编程场景

<?php
// 两个学期的选课记录对比
$semester1 = [
    "code001" => "PHP基础",
    "code002" => "MySQL教程",
    "code003" => "JavaScript入门",
    "code004" => "Laravel框架"
];

$semester2 = [
    "code001" => "PHP基础",
    "code002" => "Python基础",    // 换课了
    "code003" => "JavaScript入门",
    "code005" => "数据结构"        // 新学生
];

// 找出哪些学生换课了(键名相同但值不同)
$changed = array_diff_assoc($semester1, $semester2);
// 找出退课的学生(在semester1中有但在semester2中没有)
$dropped = array_diff_key($semester1, $semester2);
// 找出新选课的学生(在semester2中有但在semester1中没有)
$new = array_diff_key($semester2, $semester1);

echo "换课的学生:\n";
print_r($changed);
echo "\n退课的学生:\n";
print_r($dropped);
echo "\n新选课的学生:\n";
print_r($new);
?>

示例6:索引数组的

<?php
$arr1 = ["红", "绿", "蓝"];
$arr2 = ["绿", "红", "蓝"];

$diff = array_diff_assoc($arr1, $arr2);
print_r($diff);
?>

输出:

Array
(
    [0] => 红
    [1] => 绿
)

索引数组也是基于键名比较的。arr1[0]="红"和arr1[0]="红"和arr2[0]="绿"不匹配,arr1[1]="绿"和arr1[1]="绿"和arr2[1]="红"不匹配,所以前两个都返回。如果只想按值比较,用array_diff()

本节课程知识要点

  • array_diff_assoc()比较多个数组的键名+值,返回只存在于第一个数组的条目

  • array_diff()的区别:后者只比较值,忽略键名

  • 键名相同但值不同的条目会被算作差集返回

  • 键名不同但值相同的条目也会被算作差集返回

  • 支持传入多个数组进行对比

  • 多维数组只比较第一层,不递归

  • 从PHP 4.3开始可用

← PHP中的current():获取数组当前指针指向的元素 PHP中的array_diff():只比较值的数组差集 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号