array_intersect返回空数组的主因是参数类型不一致、键名规则误解、性能瓶颈或编码/空白字符干扰;需统一类型、首参作结构源、数据库层交集及预处理编码空白。

array_intersect 返回空数组?检查参数类型是否一致
PHP 的 array_intersect 严格比较值,但不检查类型——等等,其实是**检查的**:它用 ==(松散比较),不是 ===。所以 "1" 和 1 会被认为相等,但 null、false、0 容易互相误判。
常见错误现象:
- 传入的数组里混了字符串数字和整数,结果比对“成功”但逻辑不对
- 某个数组含
null,而另一组全是数字,null == 0成立,导致意外交集 - 用 JSON 解析后的数组,数字字段可能变成字符串,没 cast 就直接交集
实操建议:
- 统一预处理:用
array_map('intval', $arr)或array_map('strval', $arr)强制类型一致 - 调试时先
var_dump(array_values($arr))看真实结构,别只看print_r - 若需严格类型匹配(比如
1 !== "1"),改用array_uintersect配合function($a, $b) { return $a $b; }
多个数组交集顺序影响结果?是的,第一个数组决定键名保留规则
array_intersect 的返回值只保留**第一个数组的键名**,后续数组仅用于比对值。这意味着:即使第二个数组有更“干净”的键(如纯数字索引),结果里也沿用第一个数组的键——包括关联键、缺失键、甚至字符串键。
立即学习“PHP免费学习笔记(深入)”;
使用场景:
- 你要根据 ID 列表筛选用户数据,且希望结果保持原始用户数组的下标/ID 键
- 做权限校验:用当前用户拥有的权限($user_perms)去交集系统全部权限($all_perms),结果应以 $user_perms 的结构为准
实操建议:
- 把“结构参考源”放在第一个参数位置,别颠倒
- 如果只需要值不要键,套一层
array_values(array_intersect(...)) - 注意:键名重复不会合并,原样保留;若第一个数组有重复值,对应键都会出现在结果中
性能差?大数据量下别硬刚 array_intersect
array_intersect 时间复杂度是 O(n×m),两个数组各 1 万元素,最坏要 1 亿次比对。PHP 7.4+ 虽有优化,但没变算法本质。
性能影响明显的情况:
- 从数据库查出两组 ID(各 5k+),直接丢给
array_intersect找共同 ID - 循环中反复调用,比如每条订单都算一次交集
实操建议:
- 优先把交集逻辑推到数据库层:
WHERE id IN (SELECT id FROM ...)或JOIN - 内存够用时,用
array_flip建哈希表加速:把第二个数组array_flip后用isset($lookup[$val])过滤第一个数组,O(n+m) - 避免在
foreach里调用array_intersect;提前算好交集结果复用
中文字符或特殊符号交集失败?编码和空白字符在捣鬼
array_intersect 不做 trim、不处理编码差异。一个数组里是 "苹果 "(带空格),另一个是 "苹果",它们就不相等;UTF-8 和 GBK 混用时,同字节序列可能被解释成不同字符。
常见错误现象:
- 从 Excel 导入的数组含不可见空格(U+00A0 或 \t\n),肉眼无法分辨
- 前端传来的 JSON 中文字段被自动转义,后端没
urldecode或json_decode就直接参与交集
实操建议:
- 预处理加一步:
array_map('trim', $arr),必要时用mb_trim(自定义函数)处理全角空格 - 确认所有数据统一 UTF-8 编码,可用
mb_detect_encoding快速抽检 - 调试时用
bin2hex($str)看真实字节,比echo更可靠
交集看着简单,但类型、键名、性能、编码这四块,漏掉任何一块都容易半夜收到告警。











