mitmario.dev

foreach

PHP Sandbox 4 Min Lesezeit 4 BeispieleLektion 5 von 7

Diese Lektion leiht sich eine Kleinigkeit aus Abschnitt 5, nämlich die Liste. Eine Liste schreibst du in eckigen Klammern, die Einträge mit Komma getrennt: ["rot", "gruen", "blau"]. Mehr brauchst du hier nicht zu wissen, alles Weitere über Listen kommt im nächsten Abschnitt.

Ohne Zähler durch die Liste

Eine Liste durchgehen
<?php

$farben = ["rot", "gruen", "blau"];

foreach ($farben as $farbe) {
    echo "Farbe: $farbe\n";
}

echo "Fertig, ohne einen einzigen Zaehler.\n";

foreach bekommt die Liste, dann das Wort as, dann einen Namen für den Wert, den es gerade in der Hand hat. Der Block läuft einmal je Eintrag, und der Name enthält jedes Mal etwas anderes.

Vergleich das einen Moment mit dem for aus der letzten Lektion. Dort musstest du selbst festlegen, wo der Zähler anfängt, wie weit er läuft und in welchen Schritten. Drei Angaben, drei Gelegenheiten, sich um eins zu vertun. Hier gibt es keinen Zähler, und damit auch keinen Fehler um eins.

Deshalb die Faustregel für den Rest des Kurses: Sobald du eine Liste vor dir hast, nimm foreach. Ein for brauchst du nur noch, wenn du wirklich zählst und nicht durchgehst, so wie beim Einmaleins.

Schlüssel und Wert

Schlüssel und Wert
<?php

$farben = ["rot", "gruen", "blau"];

foreach ($farben as $nummer => $farbe) {
    echo "$nummer: $farbe\n";
}

echo "\n";

$preise = ["Brot" => 250, "Milch" => 120, "Kaffee" => 490];

foreach ($preise as $ware => $cent) {
    echo "$ware kostet $cent Cent\n";
}

Manchmal willst du nicht nur den Wert, sondern auch, an welcher Stelle er steht. Dafür gibt es die zweite Form mit einem Doppelpfeil: erst der Schlüssel, dann der Wert.

Bei einer einfachen Liste ist der Schlüssel die Position, und sie fängt bei null an. Der erste Eintrag hat also die Nummer 0, und das ist der Grund, warum die dritte Schleife aus Lektion 4.4 so aussah, wie sie aussah.

Der zweite Teil des Beispiels zeigt, wofür diese Form wirklich da ist. Eine Liste kann statt Zahlen auch eigene Schlüssel haben, hier Warennamen. Dann ist der Schlüssel der Name und der Wert der Preis, und beide bekommst du in einem Durchgang. Auch das gehört eigentlich in Abschnitt 5, aber ohne diesen einen Handgriff wäre foreach nur die halbe Lektion.

Die Preise stehen dort übrigens in Cent, nicht in Euro. Das ist der Rat aus Lektion 2.3: Beträge als ganze Zahlen führen und erst beim Anzeigen umrechnen.

Wofür man das im Alltag nimmt

Eine Liste, die zur Seite wird
<?php

$aufgaben = ["Einkaufen", "Rechnung zahlen", "Mia anrufen"];

echo "<h2>Meine Liste</h2>\n";
echo "<ul>\n";

foreach ($aufgaben as $aufgabe) {
    echo "  <li>$aufgabe</li>\n";
}

echo "</ul>\n";

Hier kommt der häufigste Einsatz überhaupt, und deshalb ist es das einzige Beispiel dieses Abschnitts, bei dem ein Server läuft und im Reiter Browser eine Seite steht. Eine Liste im Programm, eine Liste auf dem Bildschirm: Das Gerüst drumherum wird einmal ausgegeben, die <li>-Zeilen kommen aus der Schleife.

Sieh dir beide Stellen an. Im Browser steht die Liste mit Aufzählungspunkten. Tipp dann php index.php im Terminal: Da steht dieselbe Ausgabe noch einmal, aber als Zeichen, spitze Klammer, l, i. Derselbe Code, zweimal angesehen, genau wie beim Heredoc in Lektion 3.3.

In den anderen fünf Lektionen dieses Abschnitts läuft kein Server, und das ist kein Ausfall. Dort geht es um Zahlen, Zweige und Zähler, und dafür ist die Ausgabe im Terminal die richtige Ansicht. Ab Abschnitt 10 kehrt sich das Verhältnis um: Dann gibt fast jede Lektion eine Seite aus, und diese Schleife hier ist die Zeile, mit der du sie füllen wirst.

Die Falle mit dem Und-Zeichen

Die Falle mit dem Und-Zeichen
<?php

$zahlen = [1, 2, 3];

foreach ($zahlen as &$zahl) {
    $zahl = $zahl * 2;
}

echo "Nach dem Verdoppeln: ", implode(", ", $zahlen), "\n";

foreach ($zahlen as $zahl) {
    // Dieser Block tut nichts. Trotzdem geht hier etwas kaputt.
}

echo "Nach der zweiten Schleife: ", implode(", ", $zahlen), "\n";

Eine Sache fehlt noch, und sie ist unangenehm. Innerhalb der Schleife arbeitest du mit einer Kopie des Wertes. Änderst du sie, bleibt die Liste, wie sie war. Willst du die Liste wirklich ändern, setzt du ein & vor den Namen, und dann arbeitest du am Eintrag selbst.

Das funktioniert, und im Beispiel steht danach richtig 2, 4, 6. Der Ärger kommt danach. Der Name bleibt nach der Schleife auf den letzten Eintrag zeigen, und die nächste foreach-Schleife, die denselben Namen benutzt, schreibt bei jedem Durchgang in diesen letzten Eintrag hinein. Am Ende steht dort 2, 4, 4, und der zweite Block hat dabei nicht eine einzige Zeile Code enthalten.

Im Reiter Debug siehst du beides passieren. Nach Aufzeichnen wächst zahlen in der ersten Schleife Schritt für Schritt, [2, 2, 3], dann [2, 4, 3], dann [2, 4, 6]. Der zweite Block hat keine Anweisung und taucht deshalb gar nicht auf, aber an der letzten echo-Zeile steht zahlen=[2, 4, 4] und daneben zahl=4: Die Liste hat sich geändert, ohne dass eine Zeile sie angefasst hat.

Du musst dir das nicht merken. Merk dir stattdessen die Regel: Kein & in foreach. Wenn du eine Liste umbauen willst, bau eine neue auf, statt die alte im Vorbeigehen zu verändern. Wie das geht, steht in Abschnitt 5. Und wenn dir das & in fremdem Code begegnet, weißt du jetzt, wo du bei einem unerklärlichen letzten Eintrag nachsehen musst.

Zum Mitnehmen

Die Schleife, die du in PHP am häufigsten schreiben wirst. foreach geht eine Liste von vorn bis hinten durch und nimmt dir dabei genau das ab, was bei for am leichtesten schiefgeht: den Zähler.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 4 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe, dein Code läuft auf einem Server

    Öffnet sich mit dem Basis Konto.