PHP foreach Schleifen

Die PHP foreach Schleife ist wunderbar geeignet kleine Datensätze gut lesbar zu verarbeiten. Der Schleifenkopf ist als Fließtext lesbar. Und statt wie bei einer for-Schleife über den Index auf Elemente zuzugreifen, bekommst Du den aktuellen Wert als temporäre Variable.

PHP foreach: einfaches Beispiel

Bevor wie lange darüber reden, hier ein Beispiel:

$numbers = [1, 2, 3, 4, 5];
$sum = 0;

foreach ($number as $currentNumber) {
    $sum += $currentNumber;
}

echo $sum;

Der Text erklärt sich eigentlich selbst und der Sinn der Schleife ist auf den ersten Blick erkennbar. Zumindest besser also bei dem Pendant als for-Loop:

$numbers = [1, 2, 3, 4, 5];
$numberCount = count($numbers);
$sum = 0;

for ($i = 0; $i < $numberCount; $i++) {
    $sum += $numbers[$i];
}

Sicher auch nicht unlesbar. Aber ich finde die foreach Lösung ist die besser Wahl.

Assoziative Arrays mit foreach

Neben der besseren Lesbarkeit gibt es noch ein wichtiges Feature. Der Schlüsselwert im Array muss nicht bei 0 beginnen und dann hochgezählt werden (0, 1, 2…). Da ist eine foreach-Schleife genial:

$wizards = ['Harry' => 'Gryffindor', 'Ron' => 'Gryffindor', 'Draco' => 'Slytherin'];

foreach ($wizards as $name => $house) {
    echo "$name is part of $house\n";
}

Die temporären Variablen (hier $name und $house) sind frei wählbar. Ich empfehle damit den Inhalt zu beschreiben. Häufig findest Du etwas wie:

$wizards = ['Harry' => 'Gryffindor', 'Ron' => 'Gryffindor', 'Draco' => 'Slytherin'];

foreach ($wizards as $k => $v) {
    echo "$k is part of $v\n";
}

Das $k steht für Key und $v für Value. An der Stelle wo die Variable verwendet wird ergibt sich ihr Inhalt nicht. Du musst erst weiter oben nachschauen. Also lieber gleich vernünftige Bezeichner nutzen.

Also immer foreach statt for?

Einen klaren Gewinner gibt es nicht. Es kommt auf die Situation an.

Meine Standardlösung ist foreach. Arrays und kleinere Datensätze verarbeite ich quasi immer mit foreach. Ganz einfach wegen der Lesbarkeit.

Theoretisch hat in manchen Situationen die for-Schleife minimal bessere Performance. Aber selbst bei 10.000 Datensätzen ist das irgendwo im Bereich von 0.0000…

Trotzdem hat auch die for-Variante ihre Vorzüge. Zum Beispiel:

  • Wenn ohnehin ein Schleifenzähler benötigt wird
  • Oder es um tausende Datensätze geht.

Interessant ist zudem die Verwendung als Referenz.

Werte in foreach als Referenz

Die Werte aus den Arrays werden als Kopie übergeben (pass-by-value). Wird ein Array, eine ArrayCollection oder andere Strukturen verarbeitet? Dann wird jeder Wert in die Variablen kopiert.

Das kostet Speicher und Zeit. Bei kleinen Datenmengen und einfachen Strings fällt es nicht ins Gewicht.

Wenn Du tausende Datensätze aus einer Datenbank liest, Objekte im Array liegen und komplexe Datenstrukturen kopiert werden müssen, summieren sich Millisekunden aber schon.

Die Lösung? Die Werte nicht mehr kopieren, sondern nur eine Referenz übergeben. Du hast viele Daten (1017 Objekte) aus einer Datenbank zu verarbeiten:

$products = [<Object 1>, <Object 2>, ..., <Object 1017>];

Mit foreach alles einzeln durchlaufen bedeutet, jedes Objekt wird einmal kopiert. Die alternative Version und somit Syntax sieht wie folgt aus:

foreach ($products as &$currentProduct) {
    echo $currentProduct->getName();
}

Du kannst ganz normal auf das Objekt zugreifen. Aber durch das vorgestellte Symbol (&) wird der Verweis im Speicher auf das Original-Objekt übergeben.

Du greifst also auf das ursprüngliche Objekt zurück. Es gibt keine Kopie.

Da ist jedoch Vorsicht geboten. Es ist Fluch und Segen zugleich. Alle Änderungen an dem Element wirken sich auch auf die Originaldaten aus.

Das ist in manchen Fällen nicht gewollt. Ändern sich plötzlich auch Werte an unerwarteter Stelle, ist das vielleicht der Grund.

Link zur PHP Dokumentation