Sobald in PHP mehrere Listen aufeinandertreffen, taucht früher oder später die Frage auf, welche Einträge in beiden vorkommen. Genau diese Mengenlehre-Operation deckt array_intersect() ab und liefert die Schnittmenge in einem Aufruf. Das Tutorial zeigt die Hauptfunktion sowie die zwei Schwestern array_intersect_key() und array_intersect_assoc() mit Praxisbeispielen aus Berechtigungs-Checks, Whitelist-Filtern und Versions-Diffs.
Was macht PHP array_intersect()?
Wer in PHP wissen will, welche Werte in mehreren Arrays gemeinsam vorkommen, sucht nach einer Schnittmengen-Funktion aus der Mengenlehre. Genau dafür gibt es PHP array_intersect: Die Funktion vergleicht das erste Array mit beliebig vielen weiteren Arrays und liefert ein Array, das nur die Werte enthält, die in allen Eingaben vorkommen. Aus zwei Mannschaftslisten wird so die Liste der Spieler, die in beiden Teams stehen.

Bevor die Schwester-Funktionen array_intersect_key und array_intersect_assoc ins Spiel kommen, lohnt ein Blick auf die typischen Praxis-Szenarien wie Berechtigungs-Checks und Whitelist-Filter.
So intuitiv das klingt, so verbreitet ist die Anwendung im realen PHP-Code. PHP array_intersect() steckt hinter Berechtigungs-Prüfungen, Whitelist-Filtern, Tag-Vergleichen und Such-Filtern, die mehrere Kriterien kombinieren. Daneben gibt es zwei verwandte Funktionen, array_intersect_key() und array_intersect_assoc(), die das Vergleichs-Verhalten gezielt anpassen. Das Tutorial zeigt alle drei mit Praxisbeispielen.
Syntax und Rückgabewert
Die Signatur ist kompakt und nutzt variadische Argumente, sodass beliebig viele Arrays übergeben werden können.
<?php
array_intersect(array $array, array ...$arrays): array
Der Rückgabewert ist immer ein Array. Es enthält die Werte aus dem ersten Array, die in allen weiteren Arrays ebenfalls vorkommen. Die Schlüssel des ersten Arrays bleiben dabei erhalten, was im ersten Moment ungewohnt aussieht. Wer ein neu indiziertes Array braucht, ruft anschließend array_values() darauf an.
Erstes Beispiel: Spieler in zwei Mannschaften
Zum Einstieg ein klassisches Beispiel. Zwei Mannschaftslisten liegen vor, und PHP array_intersect() liefert die Schnittmenge.
<?php
$liste1 = ['Anna', 'Ben', 'Cara', 'Dirk'];
$liste2 = ['Ben', 'Dirk', 'Eva'];
print_r(array_intersect($liste1, $liste2));
/* Array ( [1] => Ben [3] => Dirk ) */
Das Ergebnis enthält die Spieler, die in beiden Listen vorkommen. Die Schlüssel 1 und 3 stammen aus der Originalposition in $liste1. Wer ein durchnummeriertes Array braucht, kann das Resultat einfach mit array_values(array_intersect(...)) umindizieren. Im nächsten Schritt zeigt sich, wie sich PHP array_intersect() bei mehreren Arrays verhält.
Schnittmenge dreier oder mehrerer Arrays
Mit jedem zusätzlichen Array wird die Schnittmenge strenger, weil ein Wert in allen Arrays vorkommen muss, um im Ergebnis zu landen.
<?php
$array1 = [1, 2, 3, 4, 5];
$array2 = [2, 3, 4, 6];
$array3 = [3, 4, 7];
print_r(array_intersect($array1, $array2, $array3));
/* Array ( [2] => 3 [3] => 4 ) */
Die Werte 3 und 4 sind die einzigen, die in allen drei Arrays vorkommen. Das Pattern eignet sich perfekt, wenn etwa ein Such-Filter mehrere Kriterien gleichzeitig anwenden soll und nur die Treffer interessieren, die alle Kriterien erfüllen. PHP array_intersect() macht aus mehreren foreach-Schleifen einen einzigen Aufruf.
Praxisfall Berechtigungs-Check
Eine sehr häufige Anwendung ist der Berechtigungs-Check. Ein User hat eine Liste von Rollen, für eine Aktion ist mindestens eine bestimmte Rolle nötig. Die Prüfung "hat mindestens eine der nötigen Rollen" lässt sich mit PHP array_intersect() in einer Zeile schreiben.
<?php
$user_rollen = ['leser', 'editor'];
$noetig = ['editor', 'admin'];
if (!empty(array_intersect($user_rollen, $noetig))) {
echo 'Zugriff erlaubt';
} else {
echo 'Zugriff verweigert';
}
/* Ausgabe: Zugriff erlaubt, weil "editor" in beiden Listen ist */
Die Kombination !empty(array_intersect(...)) ist ein idiomatisches PHP-Pattern für "haben die beiden Listen mindestens einen gemeinsamen Wert?". Wer das Pattern häufig braucht, lagert es in eine kleine Helper-Funktion hasAnyRole(array $userRoles, array $needed): bool aus.
array_intersect_key für Schlüssel-Vergleich
Manchmal ist nicht der Wert, sondern der Schlüssel das Vergleichskriterium. Klassisches Beispiel ist eine Whitelist von erlaubten Feldern, die aus einem größeren Datensatz herausgefiltert werden soll. array_intersect_key() liefert nur die Einträge, deren Schlüssel in beiden Arrays vorkommen.
<?php
$daten = [
'name' => 'Anna',
'mail' => 'anna@example.com',
'pwhash' => 'irgendein-hash',
'rolle' => 'admin',
];
$whitelist = ['name' => '', 'mail' => ''];
$gefiltert = array_intersect_key($daten, $whitelist);
print_r($gefiltert);
/* Array ( [name] => Anna [mail] => anna@example.com ) */
Diese Variante ist die saubere Lösung für Whitelist-Filter etwa vor einem JSON-Response. Sensible Felder wie Passwort-Hashes oder interne IDs werden zuverlässig herausgehalten. array_diff_key bildet das Gegenstück und entfernt alle Einträge, deren Schlüssel in der zweiten Liste vorkommen. Beide zusammen decken die meisten Schlüssel-basierten Filterungen ab.
array_intersect_assoc für Schlüssel und Wert
Die strengste Variante ist array_intersect_assoc(). Sie eignet sich vor allem für assoziative Arrays und nimmt einen Eintrag nur dann in das Ergebnis auf, wenn sowohl der Schlüssel als auch der Wert in allen Arrays übereinstimmen. Damit deckt die Funktions-Familie sowohl numerische als auch assoziative Vergleiche ab.
<?php
$alt = ['name' => 'Anna', 'land' => 'DE'];
$neu = ['name' => 'Anna', 'land' => 'AT'];
print_r(array_intersect_assoc($alt, $neu));
/* Array ( [name] => Anna ) */
Im Beispiel bleibt nur name übrig, weil land zwar denselben Schlüssel, aber unterschiedliche Werte hat. Diese Variante ist perfekt, um Differenzen zwischen zwei Datensätzen zu finden, etwa für Versions-Diffs oder Audit-Logs. Wer wissen will, was beim Update tatsächlich gleich geblieben ist, nimmt array_intersect_assoc.
flowchart TD
A[Array1] --> C[Schnittmenge bilden]
B[Array2 .. ArrayN] --> C
C --> D{Wert in allen Arrays?}
D -->|Ja| E[In Ergebnis aufnehmen]
D -->|Nein| F[Wert verwerfen]
Loser Vergleich und Stolperfallen mit Typen
PHP array_intersect() vergleicht Werte über die String-Repräsentation. Das führt zu einem losen Typvergleich, bei dem 1 und '1' als gleich gelten. Wer auf strikten Typ-Vergleich angewiesen ist, sollte das wissen und gegebenenfalls einen anderen Ansatz wählen.
<?php
$a = [1, '2', 3, '4'];
$b = ['1', 2, '3', 4];
print_r(array_intersect($a, $b));
/* Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
Alle Werte gelten als gleich, obwohl die Typen unterschiedlich sind */
Wer strikt vergleichen will, kann das nicht direkt mit array_intersect erreichen, sondern braucht einen Custom-Filter, etwa mit array_filter und einem Closure, das in_array($v, $b, true) prüft. Bei Berechtigungs-Listen oder Tag-Vergleichen ist der lose Vergleich meistens unkritisch, bei numerischen Datenbank-IDs sollte man die Typen vorher konsistent machen.
Performance: array_flip plus isset als Alternative
Bei sehr großen Arrays wird PHP array_intersect() spürbar langsam, weil jedes Element des ersten Arrays gegen jedes Element der weiteren Arrays geprüft wird. Die Komplexität liegt im Worst Case bei O(n*m). Wer häufige Lookups gegen ein großes Vergleichs-Array braucht, ist mit dem array_flip plus isset Pattern oft schneller dran.
<?php
$grosse_liste = range(1, 100000);
$gesucht = [50, 200, 5000, 99999];
/* Variante 1: array_intersect, einfach aber linear */
$treffer = array_intersect($gesucht, $grosse_liste);
/* Variante 2: O(1)-Lookup mit array_flip + isset */
$lookup = array_flip($grosse_liste);
$treffer = array_filter($gesucht, fn($v) => isset($lookup[$v]));
Die zweite Variante ist bei wiederholten Lookups deutlich schneller, weil isset in konstanter Zeit arbeitet. Bei einmaligen Aufrufen mit kleinen Arrays bleibt array_intersect aber die idiomatische und gut lesbare Wahl. Wer im Code-Review die Funktion sieht, sollte überlegen, ob das Daten-Volumen wirklich passt.
Fazit
PHP array_intersect() ist eine sehr nützliche Funktion für alle Fälle, in denen die gemeinsamen Werte mehrerer Arrays gefragt sind. Sie eignet sich perfekt für Berechtigungs-Checks, Tag-Vergleiche und Such-Filter mit mehreren Kriterien. Die Schwester-Funktionen array_intersect_key() und array_intersect_assoc() decken Schlüssel-basierte und kombinierte Vergleiche ab. Wer die lose Typprüfung im Auge behält, das !empty(array_intersect(...))-Pattern für Berechtigungs-Checks beherrscht und bei sehr großen Datenmengen auf array_flip plus isset wechselt, holt aus der Funktion das Maximum heraus.