in_array($needle, $haystack) liefert true, wenn der Wert irgendwo im Array steht, und sonst false. Übergib true als drittes Argument, in_array($needle, $haystack, true), um auch denselben Typ zu verlangen; diese strikte Form solltest du standardmäßig verwenden.
in_array() schaut nur auf Werte. Um zu prüfen, ob ein Schlüssel existiert, verwendest du array_key_exists() oder isset().
Der Parameter strict
Ohne drittes Argument vergleicht in_array() mit ==, das Typen vor dem Vergleich umwandelt. Mit true vergleicht es mit ===: Wert und Typ müssen beide übereinstimmen. Der Unterschied zeigt sich, sobald das Array Zahlen und Strings mischt, und das ist bei Daten aus Formularen, URLs und CSV-Dateien häufig.
Jede Zelle unten zeigt, was == und === in PHP 8.3 für dieses Wertepaar liefern. in_array() antwortet mit true, wenn der gesuchte Wert und irgendein Element in der Tabelle für den verwendeten Modus true ergeben. Wechsle zwischen den Tabs und schau dir die Zeilen für null, true und numerische Strings an.
| $a == $b | true | false | null | 0 | 1 | "0" | "1" | "" | "abc" | "10" | "1e1" | 10 | [] |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| true | |||||||||||||
| false | |||||||||||||
| null | |||||||||||||
| 0 | |||||||||||||
| 1 | |||||||||||||
| "0" | |||||||||||||
| "1" | |||||||||||||
| "" | |||||||||||||
| "abc" | |||||||||||||
| "10" | |||||||||||||
| "1e1" | |||||||||||||
| 10 | |||||||||||||
| [] |
Eine Regel hat sich in PHP 8 geändert: Ein nicht numerischer String ist nicht mehr gleich 0, also ist in_array('abc', [0]) heute false, war in PHP 7 aber true. Code für PHP 7 hat sich manchmal darauf verlassen, ein Grund mehr, true zu übergeben und nicht von den Umwandlungsregeln abzuhängen. Die Seite zu Vergleichsoperatoren erklärt sie vollständig.
in_array ohne Groß- und Kleinschreibung
in_array() vergleicht Strings exakt, also sind 'PHP' und 'php' verschieden. Wandle vor der Prüfung sowohl den gesuchten Wert als auch das Array in Kleinbuchstaben um. mb_strtolower() kommt auch mit Umlauten, Akzenten und nicht lateinischen Buchstaben zurecht.
Mehrere Werte auf einmal prüfen
in_array() nimmt einen gesuchten Wert. Für mehrere vergleichst du die Arrays als Mengen: array_diff() liefert die gesuchten Werte, die fehlen, ein leeres Ergebnis bedeutet also, dass alle vorhanden sind, und array_intersect() liefert die gefundenen.
array_diff() und array_intersect() vergleichen Werte als Strings, also zählen 1 und '1' dort als gleich.
in_array bei einem mehrdimensionalen Array
in_array() sucht nicht in verschachtelten Arrays. Um zu prüfen, ob eine Zeile ein Feld mit einem bestimmten Wert hat, ziehst du dieses Feld zuerst mit array_column() heraus und durchsuchst dann die flache Liste.
Die letzte Zeile zeigt, dass der gesuchte Wert selbst ein Array sein kann: Er passt zu einer Zeile, die identisch ist, mit gleichen Schlüsseln, Werten und gleicher Reihenfolge.
in_array vs array_search vs isset
Alle drei beantworten die Frage „ist es da?“, liefern aber Unterschiedliches und laufen unterschiedlich schnell:
| Aufruf | Liefert | Tempo bei einem großen Array |
|---|---|---|
in_array($v, $arr, true) | true oder false | durchsucht jedes Element |
array_search($v, $arr, true) | den Schlüssel oder false | durchsucht jedes Element |
isset($set[$v]) | true oder false | ein Hash-Lookup |
Verwende array_search(), wenn du wissen musst, wo der Wert steht. Wenn du viele Werte gegen dieselbe große Liste prüfst, drehst du die Liste einmal um, sodass ihre Werte zu Schlüsseln werden, und verwendest isset().
Die Zeiten ändern sich von Durchlauf zu Durchlauf, der Abstand aber nicht: Der Lookup mit isset() bleibt flach, während in_array() mit der Größe der Liste wächst. array_flip() funktioniert nur mit String- und Ganzzahlwerten, und Duplikate fallen zu einem Schlüssel zusammen, was für eine Prüfung auf Enthaltensein keine Rolle spielt.
Häufig gestellte Fragen
Was macht der dritte Parameter von in_array?
Er schaltet den strikten Vergleich ein. in_array($x, $arr, true) vergleicht mit ===, also muss neben dem Wert auch der Typ übereinstimmen: in_array('1', [1, 2], true) ist false. Ohne ihn vergleicht PHP mit == und wandelt Typen vorher um.
Sollte ich in_array immer im Strict-Modus verwenden?
Meistens ja. Im lockeren Modus liefern in_array(null, [0]), in_array(true, ['any string']) und in_array('1e1', ['10']) alle true. Lass ihn nur weg, wenn '5' aus einem Formular bewusst zur Ganzzahl 5 passen soll.
Wie mache ich in_array unabhängig von Groß- und Kleinschreibung?
Wandle beide Seiten in Kleinbuchstaben um: in_array(strtolower($needle), array_map('strtolower', $haystack), true). Verwende mb_strtolower, wenn der Text Nicht-ASCII-Buchstaben enthalten kann.
Wie prüfe ich, ob mehrere Werte in einem Array sind?
Um alle zu verlangen, prüfst du, dass nichts übrig bleibt: !array_diff($needles, $haystack). Um mindestens einen zu verlangen, prüfst du auf eine Überschneidung: (bool) array_intersect($needles, $haystack).
Ist in_array langsam?
Es durchsucht das Array Element für Element und ist deshalb langsam bei großen Arrays, die oft geprüft werden. Dreh das Array einmal mit $set = array_flip($haystack); um und verwende isset($set[$value]), das ist ein einziger Hash-Lookup.