Menu

PHP foreach-Schleife: Key Value, Index und Referenz

foreach ($array as $value) besucht jedes Element eines Arrays, und foreach ($array as $key => $value) liefert zusätzlich den Schlüssel. Mit Index ermitteln, Werte per Referenz ändern und der Falle mit unset(), break und continue, verschachtelten Arrays, list() in foreach und HTML bauen.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

foreach ($array as $value) führt den Block einmal für jedes Element aus, wobei $value das aktuelle Element ist. Um zusätzlich den Schlüssel zu bekommen, schreibst du foreach ($array as $key => $value).

foreach funktioniert mit jedem Array, egal welche Schlüssel es hat, und du musst nie einen Zähler verwalten oder eine Länge prüfen. Es ist die Schleife, die du in PHP am häufigsten schreiben wirst.

Über Schlüssel und Werte iterieren

In $key => $value wählst du die Namen selbst: $name => $age, $id => $user, $k => $v. Bei einer Liste sind die Schlüssel die Positionen 0, 1, 2. Bei einem assoziativen Array sind es die String-Schlüssel, die du festgelegt hast.

Die letzte Schleife zeigt ein Detail, das überrascht: Ein String-Schlüssel, der wie eine ganze Zahl aussieht, etwa "1", wird als Ganzzahl 1 gespeichert. "01" ist keine kanonische Ganzzahl und bleibt deshalb ein String.

Den Index in foreach bekommen

Bei einer Liste ist der Schlüssel der Index, also reicht foreach ($items as $i => $item). Bei einem assoziativen Array gibt es keine numerische Position, also führst du einen Zähler. Um das erste oder letzte Element anders zu behandeln, vergleichst du den Schlüssel mit array_key_first() oder array_key_last().

Die letzte Schleife gibt zwischen den Namen ein Komma aus, aber nicht nach dem letzten. Für genau diese Aufgabe ist implode(', ', array_keys($scores)) kürzer; die Prüfung mit array_key_last() ist für Fälle, in denen der letzte Durchlauf eine andere Logik braucht, nicht nur ein anderes Trennzeichen.

Array-Werte in foreach ändern (per Referenz)

$value ist eine Kopie. Eine Zuweisung daran ändert nichts im Array. Um das Array zu ändern, iterierst du entweder per Referenz mit &$value oder schreibst über den Schlüssel zurück.

Beides funktioniert. Die Version mit Schlüssel hinterlässt nach der Schleife keinen versteckten Zustand, deshalb bevorzugen viele Teams sie. Um ein neues Array zu bauen, statt eines zu ändern, ist array_map() eine weitere Möglichkeit.

Eine verwandte Frage: Was passiert, wenn du während der Schleife Elemente hinzufügst? Ein normales foreach läuft über das Array, wie es beim Start der Schleife war, also erzeugt $prices[] = ... darin keine zusätzlichen Durchläufe. Eine Referenzschleife läuft über das lebende Array und besucht die neuen Elemente.

Die Falle mit unset() bei foreach per Referenz

Nach foreach ($arr as &$v) ist die Variable $v weiterhin eine Referenz auf das letzte Element des Arrays. Wenn du den Namen $v später in einer normalen Schleife wiederverwendest, schreibt jeder Durchlauf in dieses letzte Element. Führe das hier aus und schau dir das letzte Element an:

Die zweite Schleife weist $letters[2] nacheinander A, dann B und dann den Wert des letzten Elements selbst zu, und beim letzten Durchlauf enthält dieser Platz schon B. Die Lösung ist eine Zeile: Setze unset($v); direkt nach jedes foreach per Referenz.

break und continue in foreach

break verlässt die Schleife, continue springt zum nächsten Element. Ein übliches Muster ist die Suche: Iteriere, bis du findest, was du brauchst, und dann break, damit der Rest des Arrays nicht mehr geprüft wird.

In verschachtelten Schleifen verlässt break 2 die innere Schleife und die äußere darum herum, und continue 2 springt zum nächsten Durchlauf der äußeren Schleife.

Verschachtelte Arrays und foreach mit list()

Datenzeilen sind Arrays in einem Array. Iteriere über die Zeilen und dann über jede Zeile, oder hol die Felder mit Array-Destructuring direkt in der foreach-Zeile heraus: [$a, $b] für Listen, ['key' => $var] für assoziative Zeilen. list($a, $b) ist die ältere Schreibweise von [$a, $b].

Die Seite zu Destructuring zeigt mehr zur Syntax [...] =, einschließlich übersprungener Elemente und verschachtelter Muster.

Eine HTML-Liste oder -Tabelle mit foreach bauen

In einem Template hält die Doppelpunkt-Form foreach (...): mit endforeach; die Schleife zwischen Tags lesbar. Dieser Block baut eine Tabelle, und die Spaltenüberschriften sind Links: Klicke im Tab Page auf eine, und dasselbe Skript läuft erneut mit gesetztem $_GET['sort'], sodass die Zeilen in neuer Reihenfolge zurückkommen.

Zwei Gewohnheiten aus diesem Block lohnen sich: Der Wert sort aus der URL wird vor der Verwendung mit einer Liste erlaubter Spalten verglichen, und jeder Wert, der ins HTML ausgegeben wird und Nutzertext enthalten könnte, läuft durch htmlspecialchars().

foreach über null, ein leeres Array oder ein Objekt

Ein leeres Array ist kein Problem: Der Rumpf läuft nie. null, ein String oder eine Zahl schon: PHP gibt eine Warnung aus und überspringt die Schleife. Bei $tags = null; foreach ($tags as $tag) wird ausgegeben:

Warning: foreach() argument must be of type array|object, null given in /var/www/html/index.php on line 4

Das passiert am häufigsten bei Daten, die manchmal fehlen, etwa einem optionalen Feld in dekodiertem JSON. Fall mit ?? auf ein leeres Array zurück:

foreach ($data['tags'] ?? [] as $tag) {
    echo $tag;
}

Das object in dieser Meldung ist ernst gemeint: foreach über ein Objekt besucht seine Eigenschaften, die von der Stelle der Schleife aus sichtbar sind (außerhalb der Klasse die öffentlichen), mit dem Eigenschaftsnamen als Schlüssel. Klassen, die Iterator oder IteratorAggregate implementieren, und Generatoren entscheiden selbst, was ein foreach sieht.

foreach vs for vs array_map

VerwendenWann
foreachDu willst jedes Element, mit oder ohne Schlüssel. Funktioniert mit jedem Array, Liste oder assoziativ.
forDu zählst (1 bis 100, jedes zweite Element) oder brauchst Nachbarn über den Index ($a[$i - 1]). Siehe die for-Schleife.
array_map()Du baust ein neues Array, indem du jedes Element umwandelst, oft als Einzeiler mit fn.
array_filter()Du behältst nur die Elemente, die einen Test bestehen.

Eine schnelle Entscheidungshilfe: Wenn der Schleifenrumpf nur einen neuen Wert pro Element berechnet, sagt array_map(fn($x) => $x * 2, $a) das in einer Zeile. Wenn er Seiteneffekte hat (ausgeben, speichern, mehrere Dinge auf einmal zählen) oder break braucht, schreib das foreach.

Häufig gestellte Fragen

Wie bekomme ich in einer PHP-foreach-Schleife Schlüssel und Wert?

Mit der Form =>: foreach ($array as $key => $value) { echo "$key: $value"; }. Bei einer einfachen Liste ist der Schlüssel der Index (0, 1, 2); bei einem assoziativen Array ist es der String-Schlüssel, etwa 'name'.

Wie bekomme ich in einer PHP-foreach-Schleife den Index?

Bei einer Liste ist der Schlüssel schon der Index: foreach ($items as $i => $item). Bei einem assoziativen Array führst du einen eigenen Zähler: Setze $i = 0; vor der Schleife und $i++ am Ende jedes Durchlaufs. array_key_first() und array_key_last() sagen dir, welcher Schlüssel der erste oder letzte ist.

Wie ändere ich in PHP Array-Werte in einer foreach-Schleife?

Iteriere per Referenz mit &: foreach ($prices as &$price) { $price *= 2; } unset($price);. Oder schreib über den Schlüssel zurück: foreach ($prices as $key => $price) { $prices[$key] = $price * 2; }. Ein einfaches $price = ... ändert nur eine Kopie.

Warum dupliziert foreach per Referenz in PHP das letzte Element?

Nach foreach ($arr as &$v) ist $v weiterhin eine Referenz auf das letzte Element. Ein zweites foreach ($arr as $v) schreibt dann jeden Wert in diesen letzten Platz, sodass dort am Ende der vorletzte Wert wiederholt wird. Rufe direkt nach der Referenzschleife unset($v); auf.

Wie breche ich in PHP aus einer foreach-Schleife aus?

break; stoppt die Schleife sofort, und continue; springt zum nächsten Element. In verschachtelten Schleifen verlässt break 2; die innere und die äußere Schleife.

Illustration der Programmiersprachen bei Coddy

Lerne mit Coddy zu programmieren

LOS GEHT'S