in_array($needle, $haystack) retorna true se o valor está em algum lugar do array e false se não está. Passe true como terceiro argumento, in_array($needle, $haystack, true), para exigir também o mesmo tipo; essa forma estrita é a que deve ser usada por padrão.
O in_array() só olha os valores. Para verificar se uma chave existe, use array_key_exists() ou isset().
O parâmetro strict
Sem o terceiro argumento, o in_array() compara com ==, que converte os tipos antes de comparar. Com true, ele compara com ===: o valor e o tipo precisam bater. A diferença aparece assim que o array mistura números e strings, o que é comum com dados de formulários, URLs e arquivos CSV.
Cada célula abaixo é o que == e === retornam para aquele par de valores no PHP 8.3. O in_array() responde true se a agulha e algum elemento dão true na tabela do modo que você usa. Alterne entre as abas e olhe as linhas de null, true e das strings numéricas.
| $a == $b | true | false | null | 0 | 1 | "0" | "1" | "" | "abc" | "10" | "1e1" | 10 | [] |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| true | |||||||||||||
| false | |||||||||||||
| null | |||||||||||||
| 0 | |||||||||||||
| 1 | |||||||||||||
| "0" | |||||||||||||
| "1" | |||||||||||||
| "" | |||||||||||||
| "abc" | |||||||||||||
| "10" | |||||||||||||
| "1e1" | |||||||||||||
| 10 | |||||||||||||
| [] |
Uma regra mudou no PHP 8: uma string não numérica não é mais igual a 0, então in_array('abc', [0]) é false hoje, mas era true no PHP 7. Código escrito para PHP 7 às vezes dependia disso, o que é mais um motivo para passar true e não depender das regras de conversão. A página sobre operadores de comparação explica essas regras por completo.
in_array sem diferenciar maiúsculas
O in_array() compara strings com exatidão, então 'PHP' e 'php' são diferentes. Deixe a agulha e o array em minúsculas antes de verificar. O mb_strtolower() também lida com letras acentuadas e não latinas.
Verificar vários valores de uma vez
O in_array() recebe uma agulha. Para várias, compare os arrays como conjuntos: array_diff() retorna as agulhas que faltam, então um resultado vazio significa que todas estão presentes, e array_intersect() retorna as agulhas encontradas.
array_diff() e array_intersect() comparam valores como strings, então ali 1 e '1' contam como iguais.
in_array num array multidimensional
O in_array() não busca dentro de arrays aninhados. Para verificar se alguma linha tem um campo com determinado valor, extraia esse campo antes com array_column() e depois busque na lista simples.
A última linha mostra que a agulha pode ser um array: ela bate com uma linha idêntica, com as mesmas chaves, valores e ordem.
in_array, array_search ou isset
Os três respondem "está lá?", mas retornam coisas diferentes e rodam em velocidades diferentes:
| Chamada | Retorna | Velocidade num array grande |
|---|---|---|
in_array($v, $arr, true) | true ou false | percorre todos os elementos |
array_search($v, $arr, true) | a chave, ou false | percorre todos os elementos |
isset($set[$v]) | true ou false | uma consulta de hash |
Use array_search() quando precisar saber onde o valor está. Quando você verifica muitos valores na mesma lista grande, inverta a lista uma vez para que os valores virem chaves, e use isset().
Os tempos mudam a cada execução, mas a diferença não: a consulta com isset() fica estável, enquanto o in_array() cresce com o tamanho da lista. O array_flip() só funciona com valores string e inteiros, e duplicados viram uma única chave, o que não importa para verificar se um valor está presente.
Perguntas frequentes
O que faz o terceiro parâmetro do in_array?
Ele liga a comparação estrita. in_array($x, $arr, true) compara com ===, então o tipo precisa bater além do valor: in_array('1', [1, 2], true) é false. Sem ele, o PHP compara com == e converte os tipos antes.
Devo usar sempre o modo estrito com in_array?
Normalmente sim. O modo frouxo faz in_array(null, [0]), in_array(true, ['any string']) e in_array('1e1', ['10']) retornarem true. Deixe-o desligado só quando você quiser de propósito que o '5' de um formulário bata com o inteiro 5.
Como faço o in_array não diferenciar maiúsculas de minúsculas?
Deixe os dois lados em minúsculas: in_array(strtolower($needle), array_map('strtolower', $haystack), true). Use mb_strtolower quando o texto puder ter letras fora do ASCII.
Como verifico se vários valores estão num array?
Para exigir todos, verifique que nada sobrou: !array_diff($needles, $haystack). Para exigir pelo menos um, verifique se há interseção: (bool) array_intersect($needles, $haystack).
O in_array é lento?
Ele percorre o array elemento por elemento, então é lento para arrays grandes verificados muitas vezes. Inverta o array uma vez com $set = array_flip($haystack); e use isset($set[$value]), que é uma única consulta de hash.