← PHP中的array_intersect():计算数组的交集 PHP中的array_intersect_uassoc():用自定义回调函数比较键名的数组交集 →

PHP中的array_intersect_key():用键名计算数组交集

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

array_intersect()比较值,array_intersect_assoc()同时比较键和值。那如果只想比较键名,不关心值是什么?

array_intersect_key()就是干这个的——比较两个或多个数组的键名,返回第一个数组中存在于其他所有数组的那些键名对应的条目。这个函数从PHP 5.1开始可用。

语法格式

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

参数说明:

参数 说明 必填?
array1 基准数组 必填
array2 第一个对比数组 必填
array3... 更多对比数组 可选

返回值: 返回一个数组,包含所有在array1中存在并且在其他所有数组中也存在的键名对应的条目。

三种交集函数的区别

函数 比较内容 匹配条件
array_intersect() 只比较值 值相等就行
array_intersect_key() 只比较键名 键名相等就行
array_intersect_assoc() 键名+值 键名和值都必须相等

示例1:基础用法

<?php
$config_default = [
    "host" => "localhost",
    "port" => 3306,
    "username" => "root",
    "timeout" => 30
];

$config_user = [
    "host" => "192.168.1.100",
    "port" => 3307,
    "charset" => "utf8"
];

$common_keys = array_intersect_key($config_default, $config_user);
print_r($common_keys);
?>

输出:

Array
(
    [host] => localhost
    [port] => 3306
)

注意:只比较键名,不比较值。hostport在两个数组中都存在(即使值不同),所以被返回。返回值用的是第一个数组的值(localhost和3306)。

示例2:多个数组比较

<?php
$schema_v1 = [
    "id" => "int",
    "name" => "string",
    "age" => "int",
    "email" => "string"
];

$schema_v2 = [
    "id" => "int",
    "name" => "string",
    "phone" => "string"
];

$schema_v3 = [
    "id" => "int",
    "name" => "string",
    "address" => "string"
];

$common_fields = array_intersect_key($schema_v1, $schema_v2, $schema_v3);
print_r($common_fields);
?>

输出:

Array
(
    [id] => int
    [name] => string
)

只有idname三个版本都有。age只在v1有,email只在v1有,phone只在v2有,address只在v3有。

示例3:索引数组的键名比较

<?php
$weekdays = ["周一", "周二", "周三", "周四", "周五"];
$workdays = ["周一", "周三", "周五"];

$common = array_intersect_key($weekdays, $workdays);
print_r($common);
?>

输出:

Array
(
    [0] => 周一
    [2] => 周三
    [4] => 周五
)

索引数组的键名是数字下标。$weekdays的下标0、2、4在$workdays中存在(因为$workdays的下标0是"周一"、下标1是"周三"、下标2是"周五"),所以被返回。注意不是按值匹配的——如果位置错乱了,结果就不一样了。

个人经验分享

  1. 什么时候用array_intersect_key?

    • 找出多个数组的共同字段(结构对比)

    • API版本兼容性检查:新版本是否包含旧版本的所有字段

    • 数据库表结构对比:找出共同列

    • 配置项合并前的交集分析

  2. 和array_intersect()的典型对比

    $a = ["apple" => 1, "banana" => 2, "cherry" => 3];
    $b = ["apple" => 100, "banana" => 200, "date" => 400];
    
    // 只比较值:1和2不在b的值里(b的值是100、200、400)
    print_r(array_intersect($a, $b));  // 空数组
    
    // 只比较键名:apple和banana在b的键名中
    print_r(array_intersect_key($a, $b));  // ["apple"=>1, "banana"=>2]
  3. 性能方面
    array_intersect_key()只比较键名,通常比array_intersect_assoc()快,因为不需要比较值。

  4. 常见组合用法

    // 从一个大数组中只提取指定键名的字段(类似于白名单)
    $allowed_keys = ["name", "email", "phone"];
    $user_data = ["id" => 1, "name" => "张伟", "email" => "test@test.com", "phone" => "1380000", "role" => "admin"];
    
    $filtered = array_intersect_key($user_data, array_flip($allowed_keys));
    // array_flip把白名单变成键名数组,然后用intersect_key过滤

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

<?php
// 场景:多个数据源的学生信息,找出公共字段
$source_db = [
    "student_id" => "varchar(20)",
    "name" => "varchar(50)",
    "age" => "int",
    "class" => "varchar(20)",
    "score" => "int"
];

$source_api = [
    "student_id" => "string",
    "name" => "string",
    "grade" => "int",
    "score" => "int"
];

$source_csv = [
    "id" => "string",
    "student_name" => "string",
    "score" => "int"
];

// 找出三个数据源都有的字段
$common_keys = array_intersect_key($source_db, $source_api, $source_csv);
print_r($common_keys);

// 找出只在数据库表中存在的字段
$db_only = array_diff_key($source_db, $source_api, $source_csv);
echo "\n只在数据库中的字段:\n";
print_r($db_only);
?>

输出:

Array
(
    [score] => int
)

只在数据库中的字段:
Array
(
    [student_id] => varchar(20)
    [name] => varchar(50)
    [age] => int
    [class] => varchar(20)
)

示例5:白名单过滤(配合array_flip)

<?php
// 用户提交的数据(可能包含恶意字段)
$submitted = [
    "username" => "代码号001",
    "email" => "user@test.com",
    "role" => "admin",
    "is_deleted" => 1,
    "password" => "123456"
];

// 允许更新的字段白名单
$allowed_fields = ["username", "email"];

// 方法1:用array_intersect_key + array_flip
$safe_data = array_intersect_key($submitted, array_flip($allowed_fields));

// 方法2:手动循环(结果一样)
$safe_data2 = [];
foreach ($allowed_fields as $field) {
    if (isset($submitted[$field])) {
        $safe_data2[$field] = $submitted[$field];
    }
}

echo "过滤后的安全数据:\n";
print_r($safe_data);
?>

输出:

过滤后的安全数据:
Array
(
    [username] => 代码号001
    [email] => user@test.com
)

这是array_intersect_key的一个经典用法:配合array_flip做输入数据的白名单过滤,防止用户提交额外字段。

示例6:数字键名的严格性

<?php
$arr1 = [1 => "apple", "2" => "banana", 3 => "cherry"];
$arr2 = ["1" => "fruit1", 2 => "fruit2", 3 => "fruit3"];

$intersect = array_intersect_key($arr1, $arr2);
print_r($intersect);
?>

输出:

Array
(
    [3] => cherry
)

键名比较时,整数1和字符串"1"被认为是不同的。所以1和"2"不匹配,"2"和2也不匹配。只有3和3(都是整数)匹配上了。这是array_intersect_key的一个容易踩的坑。

本节课程知识要点

  • array_intersect_key()返回第一个数组中存在于其他所有数组的键名对应的条目

  • 只比较键名,不比较值

  • array_intersect()的区别:后者只比较值

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

  • 配合array_flip()可以做白名单过滤

  • 数字键名和字符串数字键名会被视为不同

  • 从PHP 5.1开始可用

← PHP中的array_intersect():计算数组的交集 PHP中的array_intersect_uassoc():用自定义回调函数比较键名的数组交集 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号