array_search($value, $array) 返回第一个等于 $value 的元素的键,如果没有匹配的元素则返回 false。因为找到的键可能是 0,所以要用 !== false 检查结果,例如 if (($key = array_search('pear', $fruits)) !== false)。
如果你只需要知道有没有,in_array() 会直接告诉你。array_search() 用于你需要知道值在哪里的时候,比如要修改或删除它。
0 和 false 的陷阱
最常见的 array_search() bug:要找的值是第一个元素,它的键是 0,而 if ($key) 把 0 当成了假。于是值明明就在那里,代码却说“没找到”。用 !== false 来比较,它只匹配真正的 false。
!= false 和 if ($key) 有同样的 bug,因为 0 == false 的结果是 true。只有严格运算符才能把它们区分开。
严格搜索
和 in_array() 一样,除非把 true 作为第三个参数传入,否则 array_search() 使用 == 进行比较。宽松模式下,字符串可以匹配到数字,null 可以匹配到 0,于是返回一个你意想不到的键。
找出某个值对应的所有键
array_search() 在第一个匹配处就停止。array_keys($array, $value) 会以数组的形式返回所有匹配的键;加上 true 就是严格比较。空结果表示没有匹配,所以不会有 0 和 false 的混淆。
用 array_column 搜索多维数组
array_search() 不会查看嵌套数组的内部。对于一组行,先用 array_column() 取出要搜索的字段;这个列表中的位置和行号一一对应,所以结果就是那一行的索引。
array_column() 的输出从 0 开始重新编号,所以只有当行的编号是连续的 0, 1, 2 时才能对得上。经过 unset() 或 array_filter() 之后,编号会出现空缺;这时先对这些行执行 array_values(),或者使用最后两行那种按键查找的方式。array_column() 一页对索引键的用法有更多介绍。
不区分大小写的搜索
array_search() 对字符串做精确比较。要忽略大小写,就把两边都转成小写。array_map() 会保留键,所以你得到的键就是原数组中的键。
搜索后替换或删除
搜索通常是为了对找到的元素做点什么。拿到键之后,赋值可以修改它,unset() 可以删除它,但一定要先用 !== false 做检查:unset($arr[false]) 会悄悄删除键为 0 的元素。
常见问题
找不到值时 array_search 返回什么?
返回 false。找到值时它返回对应的键,而这个键可能是 0 或空字符串,所以要用 !== false 检查结果,永远不要用 if ($key) 或 != false。
为什么对第一个元素的 array_search 检查会失败?
索引数组的第一个元素的键是 0,而 0 是假值。所以 if (array_search('a', ['a', 'b'])) 会走进“没找到”的分支。应该写成 if (array_search('a', $arr) !== false)。
PHP 中怎样找出某个值对应的所有键?
array_search() 在第一个匹配处就停止。array_keys($array, $value, true) 会以数组的形式返回所有值匹配的键(没有匹配时为空数组)。
PHP 中怎样搜索多维数组?
把字段取出来变成一个一维列表,再搜索它:$i = array_search('ada@example.com', array_column($users, 'email'));,然后用 $users[$i] 读取那一行。当行的编号是 0, 1, 2 时这种方法有效;否则就用 foreach 循环。