mitmario.dev

match

PHP Sandbox 3 Min Lesezeit 4 BeispieleLektion 2 von 7

In Lektion 4.1 hast du eine Kette aus elseif gebaut. Sieh sie dir noch einmal an: In jeder Zeile stand dieselbe Variable, und dahinter jedes Mal ein anderer Wert. Für genau diesen Fall gibt es seit PHP 8 eine kürzere Schreibweise.

Ein Wert, viele Fälle

Ein Kürzel, viele Fälle
<?php

$status = "versandt";

$text = match ($status) {
    "neu" => "Bestellung eingegangen",
    "bezahlt" => "Zahlung erhalten",
    "versandt" => "Paket unterwegs",
    default => "Status unbekannt",
};

echo $text, "\n";

match bekommt einen Wert in runde Klammern und danach eine Liste von Zweigen. Links vom Doppelpfeil steht der Wert, mit dem verglichen wird, rechts das Ergebnis. Der Zweig default fängt alles ab, was sonst nirgends passt.

Drei Dinge fallen im Vergleich zur if-Kette sofort auf. Der geprüfte Wert steht einmal oben statt in jeder Zeile. Es gibt keine geschweiften Blöcke, sondern eine Zeile je Fall. Und das Ganze endet mit einem Semikolon, denn es ist eine einzige Anweisung und kein Block.

Das Komma hinter dem letzten Zweig darf stehen bleiben. Es sieht auf den ersten Blick nach einem Tippfehler aus und ist einer der freundlichsten Züge der Sprache: Wer später einen Zweig anhängt, ändert nur eine Zeile und nicht zwei.

Mehrere Werte in einem Zweig

Mehrere Werte in einem Zweig
<?php

$tag = "Sa";

echo match ($tag) {
    "Mo", "Di", "Mi", "Do", "Fr" => "Arbeitstag",
    "Sa", "So" => "Wochenende",
    default => "kein gueltiger Tag",
}, "\n";

$zweiter = "Mi";

echo match ($zweiter) {
    "Mo", "Di", "Mi", "Do", "Fr" => "Arbeitstag",
    "Sa", "So" => "Wochenende",
    default => "kein gueltiger Tag",
}, "\n";

Sollen mehrere Werte zum selben Ergebnis führen, schreibst du sie mit Komma nebeneinander. Im Beispiel teilen sich fünf Kürzel den Arbeitstag und zwei das Wochenende, und du brauchst dafür kein einziges ||.

Gelesen wird von oben nach unten, genau wie bei elseif. Der erste Zweig, der passt, gewinnt, alle weiteren sieht sich PHP nicht mehr an.

Wenn kein Zweig passt

Wenn kein Zweig passt
<?php

echo "Vor dem match\n";

// Der Wert ist der Text "1", die Zweige sind Zahlen.
// match vergleicht mit ===, also passt keiner davon,
// und es gibt hier absichtlich kein default.

$stufe = "1";

echo match ($stufe) {
    1 => "eins",
    2 => "zwei",
}, "\n";

echo "Diese Zeile wird nie erreicht\n";

Hier steckt der wichtigste Unterschied zu allem, was du bisher kennst, und er hat zwei Hälften.

Die erste: match vergleicht mit ===. Der Wert im Beispiel ist der Text "1", die Zweige sind die Zahlen 1 und 2. Nach den Regeln aus Lektion 3.6 sind Text und Zahl mit zwei Gleichheitszeichen gleich, mit dreien nicht. match nimmt drei, also passt kein Zweig.

Die zweite: Passt kein Zweig und gibt es kein default, ist das ein Fehler. Im Terminal steht Uncaught UnhandledMatchError: Unhandled match case '1', das Skript bricht ab, und php index.php; echo $? zeigt darunter die 255. Die Zeile nach dem match läuft nicht mehr, so wie bei der Division durch null aus Lektion 3.1.

Das klingt nach einem Nachteil und ist der Hauptgrund, match zu nehmen. Ein unbehandelter Fall ist fast immer ein Fehler im Programm, und es gibt zwei Möglichkeiten, davon zu erfahren: sofort und laut, oder drei Bildschirme später an einer leeren Stelle. Willst du wirklich alles Übrige abfangen, schreibst du ein default hin. Dann ist es eine Entscheidung und kein Versehen.

match ist ein Ausdruck, kein Block

match ist ein Ausdruck
<?php

$punkte = 92;

$note = match (true) {
    $punkte >= 90 => "sehr gut",
    $punkte >= 75 => "gut",
    $punkte >= 60 => "befriedigend",
    default => "nicht bestanden",
};

echo "$punkte Punkte: $note\n";

$anzahl = 3;
echo "Im Warenkorb: $anzahl ", match ($anzahl) {
    1 => "Buch",
    default => "Bücher",
}, "\n";

Ein if tut etwas, ein match ist etwas. Deshalb kannst du es einer Variablen zuweisen, wie im ersten Teil des Beispiels, oder direkt mitten in ein echo setzen, wie im zweiten. Ein if an derselben Stelle wäre ein Parse-Fehler.

Im ersten Teil steht ein Trick, der überraschend oft vorkommt: match (true). Damit vergleichst du nicht mehr einen Wert mit Werten, sondern suchst den ersten Zweig, dessen Bedingung wahr ist. Das ist Zeile für Zeile dieselbe Notenvergabe wie in der Challenge zu Lektion 4.1, nur ohne die geschweiften Klammern.

Wann also if und wann match? Die Faustregel für diesen Kurs: Prüfst du einen Wert gegen eine Liste fester Werte, nimm match. Prüfst du verschiedene Dinge oder willst du in einem Zweig mehrere Anweisungen ausführen, nimm if. Ein match kann nämlich pro Zweig nur einen einzigen Ausdruck aufnehmen, und das ist eine Grenze und keine Schikane: Sobald ein Zweig mehr als eine Zeile braucht, ist die Tabelle die falsche Form.

Zum Mitnehmen

Eine Kette aus elseif, in der jede Zeile denselben Wert prüft, ist viel Text für wenig Inhalt. match schreibt genau diesen Fall in einer Tabelle auf, vergleicht dabei streng und liefert am Ende einen Wert zurück.

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.