in_array($needle, $haystack) restituisce true se il valore si trova da qualche parte nell'array e false altrimenti. Passa true come terzo argomento, in_array($needle, $haystack, true), per richiedere anche lo stesso tipo; quella forma stretta è quella da usare di default.
in_array() guarda solo i valori. Per verificare se una chiave esiste, usa array_key_exists() o isset().
Il parametro strict
Senza il terzo argomento, in_array() confronta con ==, che converte i tipi prima di confrontare. Con true, confronta con ===: valore e tipo devono corrispondere entrambi. La differenza emerge appena l'array mescola numeri e stringhe, cosa comune con i dati di form, URL e file CSV.
Ogni cella qui sotto è ciò che == e === restituiscono per quella coppia di valori in PHP 8.3. in_array() risponde true se l'ago e un qualsiasi elemento danno true nella tabella per la modalità che usi. Passa da una scheda all'altra e guarda le righe di null, true e delle stringhe numeriche.
| $a == $b | true | false | null | 0 | 1 | "0" | "1" | "" | "abc" | "10" | "1e1" | 10 | [] |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| true | |||||||||||||
| false | |||||||||||||
| null | |||||||||||||
| 0 | |||||||||||||
| 1 | |||||||||||||
| "0" | |||||||||||||
| "1" | |||||||||||||
| "" | |||||||||||||
| "abc" | |||||||||||||
| "10" | |||||||||||||
| "1e1" | |||||||||||||
| 10 | |||||||||||||
| [] |
Una regola è cambiata in PHP 8: una stringa non numerica non è più uguale a 0, quindi in_array('abc', [0]) oggi è false ma in PHP 7 era true. Il codice scritto per PHP 7 a volte ci faceva affidamento, un motivo in più per passare true e non dipendere dalle regole di conversione. La pagina sugli operatori di confronto le spiega per intero.
in_array senza distinzione tra maiuscole e minuscole
in_array() confronta le stringhe esattamente, quindi 'PHP' e 'php' sono diversi. Converti in minuscolo sia l'ago sia l'array prima del controllo. mb_strtolower() gestisce anche le lettere accentate e non latine.
Verificare più valori insieme
in_array() accetta un solo ago. Per più valori, confronta gli array come insiemi: array_diff() restituisce gli aghi mancanti, quindi un risultato vuoto significa che ci sono tutti, e array_intersect() restituisce gli aghi trovati.
array_diff() e array_intersect() confrontano i valori come stringhe, quindi lì 1 e '1' contano come uguali.
in_array su un array multidimensionale
in_array() non cerca dentro gli array annidati. Per verificare se una riga ha un campo con un certo valore, estrai prima quel campo con array_column(), poi cerca nella lista piatta.
L'ultima riga mostra che l'ago può essere esso stesso un array: corrisponde a una riga identica, con le stesse chiavi, gli stessi valori e lo stesso ordine.
in_array vs array_search vs isset
Tutti e tre rispondono a "c'è?", ma restituiscono cose diverse e girano a velocità diverse:
| Chiamata | Restituisce | Velocità su un array grande |
|---|---|---|
in_array($v, $arr, true) | true o false | scorre ogni elemento |
array_search($v, $arr, true) | la chiave, oppure false | scorre ogni elemento |
isset($set[$v]) | true o false | una ricerca hash |
Usa array_search() quando ti serve sapere dove si trova il valore. Quando confronti molti valori con la stessa lista grande, inverti la lista una volta così i suoi valori diventano chiavi, e usa isset().
I tempi cambiano da un'esecuzione all'altra, ma il divario no: la ricerca con isset() resta costante mentre in_array() cresce con la dimensione della lista. array_flip() funziona solo con valori stringa e interi, e i duplicati si fondono in una chiave, cosa che non conta per un controllo di appartenenza.
Domande frequenti
A cosa serve il terzo parametro di in_array?
Attiva il confronto stretto. in_array($x, $arr, true) confronta con ===, quindi oltre al valore deve corrispondere anche il tipo: in_array('1', [1, 2], true) è false. Senza, PHP confronta con == e prima converte i tipi.
Devo usare sempre la modalità strict con in_array?
Di solito sì. La modalità debole fa restituire true a in_array(null, [0]), in_array(true, ['any string']) e in_array('1e1', ['10']). Lasciala disattivata solo quando vuoi di proposito che '5' arrivato da un form corrisponda all'intero 5.
Come rendo in_array insensibile a maiuscole e minuscole?
Converti in minuscolo entrambi i lati: in_array(strtolower($needle), array_map('strtolower', $haystack), true). Usa mb_strtolower quando il testo può contenere lettere non ASCII.
Come verifico se più valori sono in un array?
Per richiederli tutti, verifica che non resti nulla: !array_diff($needles, $haystack). Per richiederne almeno uno, verifica che ci sia una sovrapposizione: (bool) array_intersect($needles, $haystack).
in_array è lento?
Scorre l'array elemento per elemento, quindi è lento su array grandi controllati molte volte. Inverti l'array una volta con $set = array_flip($haystack); e usa isset($set[$value]), che è una sola ricerca in una tabella hash.