PHP array_intersect_key() 函数(长文讲解)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

函数定义与语法解析

PHP的array_intersect_key()函数是一个基于键名进行数组元素筛选的工具。它的核心功能是比较多个数组的键名,并返回主数组中与后续数组键名完全匹配的元素。函数的语法如下:

array_intersect_key(array $array1, array &$array2, array &$...): array
  • 参数说明
    • $array1:主数组,函数会返回其键名与后续数组匹配的元素。
    • $array2 及后续参数:需要与主数组进行键名比较的数组。
  • 返回值:返回一个新数组,包含主数组中键名与所有后续数组至少存在一次匹配的元素。

形象比喻
可以将array_intersect_key()想象为“钥匙匹配器”。主数组的键名如同一把钥匙,而其他数组的键名是锁孔。只有当钥匙(主数组键名)能同时匹配所有锁孔(其他数组键名)时,对应的元素才会被保留。


基础用法示例

比较两个数组的键名

假设我们有两个数组:

$array1 = ['a' => 1, 'b' => 2, 'c' => 3];  
$array2 = ['b' => 100, 'd' => 200];  

$result = array_intersect_key($array1, $array2);  
print_r($result);  

输出结果

Array  
(  
    [b] => 2  
)  

解释

  • $array1的键名是abc,而$array2的键名是bd
  • 只有键名b在两个数组中同时存在,因此结果仅保留了$array1中键名为b的元素。

比较多个数组的键名

当需要与多个数组比较时,只需在函数中添加更多参数:

$array3 = ['b' => 'apple', 'c' => 'banana'];  
$result = array_intersect_key($array1, $array2, $array3);  
print_r($result);  

输出结果

Array  
(  
    [b] => 2  
)  

关键点

  • 函数会逐个检查所有后续数组的键名,只有主数组的键名同时出现在所有后续数组中时,才会被保留。
  • 若后续数组中有一个不包含该键名,则主数组对应元素会被过滤掉。

参数类型与注意事项

参数必须为数组

如果参数不是数组,PHP会触发E_WARNING错误。例如:

// 错误示例:第二个参数是字符串而非数组  
$result = array_intersect_key($array1, "invalid");  

解决方法

  • 确保所有参数都是数组,或在调用前使用is_array()进行验证。

键名的大小写敏感性

PHP的键名比较是区分大小写的。例如:

$arrayA = ['Key1' => 'Value1'];  
$arrayB = ['key1' => 'lowercase'];  

$result = array_intersect_key($arrayA, $arrayB);  
// 输出为空,因为键名"Key1"和"key1"不匹配  

高级用法与技巧

处理多维数组

array_intersect_key()可以作用于多维数组,但仅比较最外层的键名。例如:

$array1 = [  
    'user' => ['name' => 'Alice', 'age' => 30],  
    'profile' => ['city' => 'Paris']  
];  

$array2 = ['user' => 'main'];  

$result = array_intersect_key($array1, $array2);  
print_r($result);  

输出结果

Array  
(  
    [user] => Array  
        (  
            [name] => Alice  
            [age] => 30  
        )  
)  

关键点

  • 函数仅检查最外层键名(如userprofile),而不会递归比较子数组的键名。

结合array_flip()反转键名与值

若需要根据值而非键名进行筛选,可以通过array_flip()反转键名和值后再操作:

$array1 = ['a' => 1, 'b' => 2];  
$array2 = [1 => 'one', 2 => 'two'];  

// 先反转$array2的键名和值  
$flipped = array_flip($array2);  

$result = array_intersect_key($array1, $flipped);  
print_r($result);  

输出结果

Array  
(  
    [1] => 1  // 键名1在$flipped中存在,因此保留  
    [2] => 2  
)  

实际应用场景

场景1:权限控制

在权限管理中,假设用户角色和权限存储在数组中:

$admin_permissions = ['create' => true, 'delete' => true, 'edit' => true];  
$user_permissions = ['read' => true, 'edit' => true];  

// 查找用户与管理员共有的权限  
$common_permissions = array_intersect_key($admin_permissions, $user_permissions);  
// 结果:['edit' => true]  

场景2:过滤表单提交数据

当需要仅保留表单提交中符合预设字段名的数据时:

$allowed_fields = ['username', 'email', 'age'];  
$_POST = ['username' => 'john', 'email' => 'john@example.com', 'password' => '123'];  

// 将允许的字段名转换为键名  
$allowed = array_flip($allowed_fields);  

// 过滤$_POST数据  
$sanitized_data = array_intersect_key($_POST, $allowed);  

常见问题与解决方案

问题1:如何比较键名而不关心值?

array_intersect_key()仅关注键名匹配,值的差异不影响结果。例如:

$array1 = ['a' => 100];  
$array2 = ['a' => 'apple'];  

$result = array_intersect_key($array1, $array2);  
// 结果保留$array1中的元素,即使值不同  

问题2:如何返回所有数组的共同键名?

若需要找到多个数组的共同键名,可以将主数组设为任意数组,并将其他数组作为参数:

$arrayA = ['a', 'b', 'c'];  
$arrayB = ['b', 'd'];  
$arrayC = ['b', 'e'];  

// 使用空数组作为主数组(键名为空)  
$common_keys = array_intersect_key($arrayA, $arrayB, $arrayC);  
// 结果为空,因为所有数组的键名不完全一致  

问题3:如何忽略键名的大小写?

可以通过strtolower()strtoupper()统一键名的大小写后再比较:

$array1 = ['KEY1' => 'Value'];  
$array2 = ['key1' => 'lowercase'];  

// 统一转为小写后比较  
$lowercase1 = array_change_key_case($array1, CASE_LOWER);  
$lowercase2 = array_change_key_case($array2, CASE_LOWER);  

$result = array_intersect_key($lowercase1, $lowercase2);  

与类似函数的区别

与array_intersect()的对比

  • array_intersect():根据比较数组元素,键名会被重置。
  • array_intersect_key():根据键名筛选元素,保留原始键名。
$array1 = ['a' => 1, 'b' => 2];  
$array2 = ['x' => 1, 'y' => 3];  

// array_intersect()比较值  
print_r(array_intersect($array1, $array2));  // 输出:[a => 1]  

// array_intersect_key()比较键名  
print_r(array_intersect_key($array1, $array2));  // 输出:空数组  

与array_diff_key()的对比

  • array_diff_key():返回主数组中键名不匹配的元素。
  • array_intersect_key():返回主数组中键名匹配的元素。

总结

PHP array_intersect_key()函数是一个功能强大的工具,尤其在需要根据键名筛选数据时。通过理解其参数规则、键名匹配逻辑以及实际应用场景,开发者可以高效地处理权限管理、表单验证等复杂需求。

关键技巧回顾

  1. 区分键名与值:函数仅关注键名匹配,值不影响结果。
  2. 多数组比较:所有后续数组的键名必须匹配主数组的键名才能保留。
  3. 灵活组合函数:结合array_flip()array_change_key_case()可扩展功能。

掌握array_intersect_key()不仅能提升代码效率,还能为解决更复杂的数组操作问题打下基础。建议读者通过实际案例反复练习,逐步加深理解。

最新发布