Abschnitt 4 · Lektion 3
switch, und warum match meistens gewinnt
switch gibt es in PHP seit den Neunzigern, und es steht in praktisch jedem Projekt, das älter ist
als PHP 8. Diese Lektion hat deshalb ein anderes Ziel als die übrigen: Du sollst switch lesen
können. Schreiben wirst du danach lieber match, und am Ende steht, warum.
Der Aufbau
<?php
$tag = "Sa";
switch ($tag) {
case "Mo":
case "Di":
case "Mi":
case "Do":
case "Fr":
echo "Arbeitstag\n";
break;
case "Sa":
case "So":
echo "Wochenende\n";
break;
default:
echo "kein gueltiger Tag\n";
} Ein switch bekommt einen Wert in runde Klammern und danach einen Block mit case-Marken. PHP
sucht die erste Marke, die zum Wert passt, springt dorthin und führt ab da alles aus, bis ein
break kommt. Trifft keine Marke, springt es zu default, falls es eines gibt.
Der letzte Satz ist der ganze Unterschied zu allem, was du bisher kennst. Ein case ist keine
Schublade, sondern ein Einsprungpunkt. Was danach kommt, läuft mit, auch wenn es zu einer anderen
Marke gehört.
Im Beispiel wird das ausgenutzt: Die fünf Werktage stehen als fünf leere case-Zeilen
untereinander, und erst hinter dem letzten steht Code. Wer bei Mo einsteigt, fällt durch bis zu
dem echo hinter Fr. So sieht in switch ein Sammelzweig aus, für den match ein einziges Komma
braucht.
Das vergessene break
<?php
$stufe = 2;
switch ($stufe) {
case 1:
$text = "klein";
break;
case 2:
$text = "mittel";
// Hier fehlt das break mit Absicht.
case 3:
$text = "gross";
break;
default:
$text = "unbekannt";
}
echo "Stufe $stufe ergibt: $text\n"; Und jetzt dieselbe Eigenschaft von ihrer schlechten Seite. Im zweiten Beispiel fehlt hinter
case 2 das break. Die Ausgabe lautet deshalb nicht mittel, sondern gross: PHP springt bei
case 2 hinein, setzt $text auf mittel, läuft weiter in case 3 hinein, überschreibt $text
mit gross und hört erst am nächsten break auf.
Es gibt keine Warnung dazu. Kein Hinweis auf dem Fehlerkanal, und php index.php; echo $? im
Terminal meldet eine 0, als wäre alles in Ordnung. Nur ein falscher Wert, der aussieht wie ein
richtiger. Das ist die teuerste Sorte Fehler, und es ist der Grund, warum ein vergessenes break
sprichwörtlich ist.
Sehen kannst du das Durchfallen trotzdem, im Reiter Debug. Nach Aufzeichnen stehen dort die
Zeilen in der Reihenfolge, in der sie gelaufen sind: erst $text = "mittel";, direkt darunter
$text = "gross"; mit dem Chip text="mittel" daneben, und erst am break steht text="gross".
Die Ausgabe zeigt dir nur das Ergebnis, die Liste zeigt dir den Weg dorthin.
Ein Trost bleibt: Der letzte Zweig braucht keines. Trotzdem schreibt man es traditionell auch dort hin, damit ein später angehängter Fall nicht plötzlich mitläuft.
Zwei Gleichheitszeichen, wieder einmal
<?php
$eingabe = "1";
switch ($eingabe) {
case 1:
echo "Der Text 1 trifft die Zahl 1\n";
break;
default:
echo "kein Treffer\n";
}
$null = 0;
switch ($null) {
case "abc":
echo "Die Null trifft den Text abc\n";
break;
default:
echo "Die Null trifft den Text abc nicht mehr\n";
} switch vergleicht mit ==, nicht mit ===. Damit gelten hier genau die Regeln aus Lektion 3.6,
und du kannst sie nicht abschalten: Im Beispiel trifft der Text "1" die Marke case 1.
Der zweite Teil zeigt, was PHP 8 daran aufgeräumt hat. Früher traf die Zahl 0 jeden Text, der sich
nicht als Zahl lesen ließ, case "abc" eingeschlossen. Heute nicht mehr, und das war eine der besten
Änderungen der Version. Der Rest der Liste aus 3.6 gilt aber weiter, "10" und "1e1" zum Beispiel
sind mit == nach wie vor dasselbe.
match hat dieses Problem nicht, weil es mit === vergleicht. Es ist der einzige der beiden, bei
dem du dir über die Sorte des Wertes keine Gedanken machen musst.
Beide nebeneinander
<?php
$rolle = "redakteur";
switch ($rolle) {
case "admin":
$rechte = "alles";
break;
case "redakteur":
$rechte = "schreiben";
break;
default:
$rechte = "lesen";
}
echo "switch: $rechte\n";
$rechte = match ($rolle) {
"admin" => "alles",
"redakteur" => "schreiben",
default => "lesen",
};
echo "match: $rechte\n"; Dieselbe Zuordnung, einmal in jeder Form. Der switch braucht zehn Zeilen, das match fünf, und drei
Unterschiede sind dabei mehr als Geschmack:
matchliefert einen Wert. Beimswitchmusst du in jedem Zweig einer Variablen etwas zuweisen und hoffen, dass du keinen vergisst. Vergisst du einen, ist die Variable danach gar nicht gesetzt, und du bekommst eine Warnung an einer ganz anderen Stelle.matchkennt kein Durchfallen. Es gibt keinbreak, das man vergessen könnte.matchbeschwert sich, wenn nichts passt. Derswitchläuft in dem Fall stillschweigend weiter, als wäre nichts gewesen.
Deshalb die Regel für diesen Kurs: match schreiben, switch lesen können. Und wenn du in einem
alten Projekt einen switch vor dir hast, dessen Ergebnis nicht stimmt, ist die erste Frage immer
dieselbe: Wo fehlt das break?
Zum Mitnehmen
switch ist der ältere Bruder von match. Du wirst ihn in jedem fremden PHP-Projekt finden, also musst du ihn lesen können. Selbst schreiben wirst du ihn nach dieser Lektion vermutlich nicht mehr, und das hat drei sehr konkrete Gründe.
Jetzt du
Basis Konto, kostenlosZu 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.