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

PHP中的array_diff():只比较值的数组差集

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

给你两个数组,你想知道第一个数组里有哪些值是第二个数组没有的。array_diff()就是干这个的——它比较两个或多个数组的,返回在第一个数组里存在、但在其他数组里不存在的那些条目。

注意:它只比较值,不关心键名是什么。这个函数从PHP 4.0就有了。

语法格式

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

参数说明:

参数 说明 必填?
array1 作为基准的数组 必填
array2 用来对比的数组 必填
array3... 更多用来对比的数组 可选

返回值: 返回一个数组,包含所有在array1中但不在其他数组中的元素。原数组的键名会保留。

核心规则

  • 只比较值,键名是什么无所谓

  • 字符串比较是区分大小写

  • 元素类型也会参与比较,整数的1和字符串的"1"不一样

示例1:基础用法

<?php
$intory_online = ["键盘", "鼠标", "显示器", "耳机", "摄像头"];
$intory_offline = ["键盘", "鼠标", "显示器"];

$only_online = array_diff($intory_online, $intory_offline);
print_r($only_online);
?>

输出:

Array
(
    [3] => 耳机
    [4] => 摄像头
)

耳机和摄像头只在线上仓库有,线下没有,所以返回来了。键名保留了原来的3和4。

示例2:多个数组比较

<?php
$all_students = ["张伟", "李芳", "王磊", "赵敏", "刘强", "陈晨"];
$class_a = ["张伟", "李芳"];
$class_b = ["王磊", "赵敏"];

$not_in_any_class = array_diff($all_students, $class_a, $class_b);
print_r($not_in_any_class);
?>

输出:

Array
(
    [4] => 刘强
    [5] => 陈晨
)

只要值出现在任何一个对比数组中,就会被排除。刘强和陈晨既不在A班也不在B班,所以返回。

示例3:区分大小写

<?php
$input = ["PHP", "JavaScript", "python", "Java"];
$reference = ["php", "JavaScript", "Python"];

$diff = array_diff($input, $reference);
print_r($diff);
?>

输出:

Array
(
    [0] => PHP
    [2] => python
    [3] => Java
)

"PHP"和"php"不一样(大小写不同),所以"PHP"被保留了。"python"和"Python"也不一样。"Java"在参考数组里没有。只有"JavaScript"匹配被排除了。

个人经验分享

  1. array_diff()、array_diff_assoc()、array_diff_key()的区别

函数 比较什么 什么时候用
array_diff() 只比较值 只关心哪些值没出现,键名不重要
array_diff_key() 只比较键名 想找出哪些键名是新出现的
array_diff_assoc() 键名+值都看 需要严格匹配键值对

举个例子你就明白了:

$a = ["id" => 1, "name" => "张伟", "score" => 85];
$b = ["id" => 1, "name" => "张伟", "score" => 90];

array_diff($a, $b);        // ["score" => 85] 因为值85不在b中
array_diff_key($a, $b);    // [] 键名都一样
array_diff_assoc($a, $b);  // ["score" => 85] 键名相同但值不同
  1. 常见使用场景

    • 找出两个列表的差异(比如新旧版本对比)

    • 检查是否有新用户加入

    • 数据去重前的准备工作

    • 权限对比:用户有的权限vs角色默认权限

  2. 性能注意事项
    array_diff()在处理大数组时效率还不错,但它是O(n*m)的时间复杂度。两个数组都是几万条的时候,运行时间会明显变长。如果数据量很大(几十万级别),建议用array_flip()isset()的方案:

    $flip = array_flip($array2);
    $diff = array_filter($array1, function($value) use ($flip) {
        return !isset($flip[$value]);
    });

    这个方法更快,因为isset是O(1)的。

  3. 键名会被保留,但不一定连续

    $result = array_diff(["a","b","c","d"], ["b","d"]);
    // 返回 [0 => "a", 2 => "c"]
    // 下标0和2,跳过了1

    如果后续需要连续索引,用array_values()包一下:array_values($result)

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

<?php
// 两个学期选修课程的变化检测
$semester1_courses = ["PHP基础", "MySQL", "JavaScript", "Laravel", "Vue"];
$semester2_courses = ["PHP基础", "Python", "JavaScript", "Django"];

// 新课程(只在第二学期有)
$new_courses = array_diff($semester2_courses, $semester1_courses);
// 取消的课程(只在第一学期有)
$removed_courses = array_diff($semester1_courses, $semester2_courses);
// 保留的课程(两个学期都有)
$kept_courses = array_intersect($semester1_courses, $semester2_courses);

echo "新增课程:\n";
print_r($new_courses);
echo "\n取消课程:\n";
print_r($removed_courses);
echo "\n保留课程:\n";
print_r($kept_courses);
?>

输出:

新增课程:
Array
(
    [1] => Python
    [3] => Django
)

取消课程:
Array
(
    [1] => MySQL
    [3] => Laravel
    [4] => Vue
)

保留课程:
Array
(
    [0] => PHP基础
    [2] => JavaScript
)

示例5:值相同但类型不同

<?php
$arr1 = [1, 2, "3", 4];
$arr2 = [1, "2", 3, 4];

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

输出:

Array
(
    [1] => 2
    [2] => 3
)

1(整数)匹配了1(整数),4匹配了4。但整数2和字符串"2"类型不同不匹配,字符串"3"和整数3类型不同不匹配。所以2和"3"被保留下来了。

本节课程知识要点

  • array_diff()只比较数组的值,忽略键名

  • 支持两个以上的数组进行对比

  • 返回第一个数组中存在、但其他数组中不存在的元素

  • 保留原数组的键名,不重新索引

  • 比较时区分大小写,也区分类型

  • array_diff_assoc()的区别:后者同时比较键名和值

  • 从PHP 4.0开始可用

← PHP中的array_diff_assoc():带键名比较的数组差集 PHP中的array_diff_key():只比较键名的数组差集 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号