Einleitung: Warum foreach nicht einfach nur „für jedes“ ist
Wenn Sie auch nur eine Woche PHP schreiben, haben Sie foreach schon hundertmal verwendet. Es ist wohl die beliebteste Schleife jedes Entwicklers: kurz, elegant, ohne überflüssige Zähler. Aber haben Sie sich schon einmal gefragt, was eigentlich unter der Haube passiert, wenn Sie foreach ($array as $value) schreiben?
Die Frage „How does PHP 'foreach' actually work?“ hat auf Stack Overflow tausende Aufrufe erhalten. Und das ist kein Zufall. Das Verhalten von foreach birgt einige Überraschungen, besonders wenn es um Referenzen, verschachtelte Schleifen und ungewöhnliche Arrays geht.
In diesem Tutorial wiederholen wir nicht nur die Syntax. Wir werfen einen Blick in die PHP-Engine, verstehen den internen Array-Zeiger, sehen, wie Iteratoren funktionieren, und lernen, Fallstricke zu vermeiden. Los geht's!
1. Anatomie von foreach: Was die Dokumentation sagt
Beginnen wir mit den Grundlagen. foreach dient zum Durchlaufen von Arrays und Objekten. Die Syntax ist einfach:
<?php$fruits = ['apple', 'banana', 'cherry'];
foreach ($fruits as $fruit) { echo $fruit . "";}// Ausgabe: apple banana cherry?>Es gibt aber auch eine zweite Form – mit Schlüssel:
<?php$prices = ['apple' => 100, 'banana' => 50];
foreach ($prices as $name => $price) { echo "$name kostet $price Rubel.";}?>Das scheint alles klar. Aber lassen Sie uns tiefer graben. PHP verarbeitet foreach anders als for oder while. Intern verwendet es den internen Array-Zeiger (internal array pointer) und einen speziellen Iterationsmechanismus.
2. Der interne Array-Zeiger: Ein geheimer Agent
Jedes Array in PHP hat einen unsichtbaren „Cursor“ – den internen Zeiger. Er zeigt auf das aktuelle Element. Die Funktionen current(), next(), prev(), end() und reset() steuern genau diesen.
Wenn Sie foreach starten, macht PHP Folgendes:
- Setzt den internen Zeiger auf das erste Element zurück (wie
reset()). - Nimmt bei jeder Iteration das Element, auf das der Zeiger zeigt.
- Verschiebt den Zeiger auf das nächste Element (wie
next()). - Wiederholt dies, bis das Ende erreicht ist.
Sehen wir uns das in Aktion an:
<?php$array = [10, 20, 30];
// Manuelle Nachbildung von foreachreset($array); // Zeiger auf erstes Elementwhile ($value = current($array)) { echo $value . " "; next($array); // Zeiger verschieben}// Ausgabe: 10 20 30?>Es gibt jedoch eine Einschränkung: Wenn das Array leer ist oder false enthält, funktioniert dieser Trick nicht. foreach hingegen funktioniert immer korrekt, da es einen zuverlässigeren internen Mechanismus verwendet – die Iteratoren.
3. Iteratoren und foreach: Der moderne Ansatz
Seit PHP 5 kann foreach nicht nur mit Arrays, sondern auch mit beliebigen Objekten arbeiten, die das Interface Traversable (oder seinen Nachkommen Iterator) implementieren.
Wenn Sie ein Objekt an foreach übergeben, ruft PHP die Methoden des Iterators auf:
rewind()– Zurücksetzen an den Anfangvalid()– Prüfen, ob ein Element vorhanden istcurrent()– Wert abrufenkey()– Schlüssel abrufennext()– Zum nächsten Element wechseln
Beispiel eines benutzerdefinierten Iterators:
<?phpclass NumbersIterator implements Iterator { private $position = 0; private $numbers = [1, 2, 3, 4, 5];
public function rewind() { $this->position = 0; }
public function current() { return $this->numbers[$this->position]; }
public function key() { return $this->position;