Menu

PHP in_array():判断值是否在数组中

in_array($needle, $haystack) 在值存在于数组中时返回 true。第三个参数传 true 可以进行严格检查,in_array('1', $ids, true),这样类型也必须一致。本文讲解 strict 参数、不区分大小写的搜索、检查多个值、多维数组,以及更快的 isset 替代方案。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

如果值在数组中的某个位置,in_array($needle, $haystack) 返回 true,否则返回 false。第三个参数传 true,即 in_array($needle, $haystack, true),可以同时要求类型相同;默认就应该使用这种严格写法。

in_array() 只检查值。要检查某个键是否存在,请用 array_key_exists() 或 isset()。

strict 参数

不传第三个参数时,in_array() 使用 == 比较,会在比较前转换类型。传入 true 时,它使用 === 比较:值和类型都必须一致。只要数组中混有数字和字符串,区别就会显现出来,而来自表单、URL 和 CSV 文件的数据经常是这样。

下表中的每个单元格是 PHP 8.3 中这对值用 == 和 === 比较的结果。在你使用的模式下,只要要查找的值和任意一个元素在表中得到 true,in_array() 就返回 true。切换标签页,看看 null、true 和数字字符串那几行。

in_array 的宽松 (==) 与严格 (===) 匹配
Point at or tap a cell to read it as PHP.
$a == $btruefalsenull01"0""1""""abc""10""1e1"10[]
true
false
null
0
1
"0"
"1"
""
"abc"
"10"
"1e1"
10
[]
Every cell computed by PHP 8.3.19.

PHP 8 改变了一条规则:非数字字符串不再等于 0,所以 in_array('abc', [0]) 如今是 false,而在 PHP 7 中是 true。为 PHP 7 写的代码有时会依赖这一点,这也是应该传 true、不依赖类型转换规则的又一个理由。比较运算符页面对这些规则有完整的讲解。

不区分大小写的 in_array

in_array() 精确比较字符串,所以 'PHP' 和 'php' 是不同的。检查之前,先把要查找的值和数组都转成小写。mb_strtolower() 还能处理带重音的字母和非拉丁字母。

一次检查多个值

in_array() 只接收一个要查找的值。如果有多个,就把数组当作集合来比较:array_diff() 返回缺少的那些值,所以结果为空就表示全部存在;array_intersect() 返回找到的那些值。

array_diff() 和 array_intersect() 按字符串比较值,所以在这里 1 和 '1' 被视为相等。

在多维数组中使用 in_array

in_array() 不会在嵌套数组内部搜索。要检查是否有某一行的某个字段等于给定值,先用 array_column() 把这个字段提取出来,再在这个一维列表中搜索。

最后一行说明要查找的值本身也可以是数组:它会匹配完全相同的一行,即键、值和顺序都相同。

in_array、array_search 和 isset 的区别

三者都能回答“它在不在里面?”,但返回的内容不同,运行速度也不同:

调用返回值在大数组上的速度
in_array($v, $arr, true)true 或 false扫描每个元素
array_search($v, $arr, true)键,或 false扫描每个元素
isset($set[$v])true 或 false一次哈希查找

需要知道值在哪个位置时,用 array_search()。如果要拿许多值和同一个大列表比对,就先把列表翻转一次,让它的值变成键,然后用 isset()。

每次运行的时间都会不同,但差距不会变:isset() 查找的耗时保持不变,而 in_array() 的耗时随列表大小增长。array_flip() 只适用于字符串和整数值,重复的值会合并成一个键,但这对判断是否存在没有影响。

常见问题

in_array 的第三个参数有什么作用?

它开启严格比较。in_array($x, $arr, true) 使用 === 比较,所以不仅值要相同,类型也必须一致:in_array('1', [1, 2], true) 返回 false。不传这个参数时,PHP 使用 == 比较,并会先转换类型。

使用 in_array 时应该总是开启严格模式吗?

通常应该。宽松模式下,in_array(null, [0])、in_array(true, ['any string']) 和 in_array('1e1', ['10']) 都会返回 true。只有当你有意让表单传来的 '5' 匹配整数 5 时,才不开启它。

怎么让 in_array 不区分大小写?

把两边都转成小写:in_array(strtolower($needle), array_map('strtolower', $haystack), true)。如果文本可能包含非 ASCII 字母,就用 mb_strtolower。

怎么判断多个值是否都在数组中?

如果要求全部存在,就检查是否有剩余:!array_diff($needles, $haystack)。如果只要求至少有一个存在,就检查是否有交集:(bool) array_intersect($needles, $haystack)。

in_array 慢吗?

它会逐个元素扫描数组,所以对大数组反复检查时会很慢。先用 $set = array_flip($haystack); 把数组翻转一次,再用 isset($set[$value]) 检查,这只需要一次哈希查找。

Coddy 编程语言插图

和 Coddy 一起学编程

开始