• Contact us
  • Documentation
  • Login
Watch a demoFree trial
Blog
Blog
BlogProduktFallstudienNachrichtenInsights
Blog

PHP 8.0 match()-Ausdrücke

PHPFeaturesVerbesserungen
24 September 2020
Larry Garfield
Larry Garfield
Direktor für Entwicklererfahrung
Teilen
Diese Seite wurde von unseren Experten auf Englisch verfasst und mithilfe einer KI übersetzt, um einen schnellen Zugriff zu ermöglichen! Die Originalversion findest du hier.

In unserer letzten Folge haben wir über kommende Verbesserungen am Typsystem von PHP gesprochen. Heute schauen wir uns ein neues Konstrukt an, das die Verzweigungslogik leistungsfähiger macht.

PHP hat seit jeher eine switch Anweisung seit jeher, die dem gleichen Konstrukt in C nachempfunden ist. Du hast sie sicher schon einmal gesehen:

<?php
switch ($var) {
    case 'a':
        $message = "The variable was a.";
        break;
    case 'b':
        $message = "The variable was c.";
        break;
    case 'c':
        $message = "The variable was c.";
        break;
    default:
        $message = "The variable was something else.";
        break;
}

print $message;

Zwar erfüllt es seinen Zweck, doch der klassische switch hat eine Reihe von Einschränkungen. Die meisten neueren Sprachen wie Go oder Rust haben sich für robustere, weniger fehleranfällige Strukturen entschieden, die unter verschiedenen Namen bekannt sind. Und nun hat auch PHP eine davon.

Hier kommt die PHP match . Im Gegensatz zu switchist PHP match ein Ausdruck. Das bedeutet, dass sie zu einem Wert ausgewertet wird, etwa so:

<?php
$message = match($var) {
    'a' => 'The variable was a',
    'b' => 'The variable was b',
    'c' => 'The variable was c',
    default => 'The variable was something else',
};

print $message;

Hier gibt es einige Dinge zu beachten:

  1. Mit switchwird jedes case mit der lockeren Gleichheit ==. Bei PHP matchwird jeder Zweig mit strikter Gleichheit verglichen, ===. Das bedeutet, dass auch die Typen übereinstimmen müssen.
  2. Jeder Zweig des match ist nur ein einzelner Ausdruck. Keine mehrzeiligen Anweisungen, nur ein einzelner Ausdruck, der ausgewertet wird. Wenn du komplexe Logik benötigst, mache daraus eine Funktion oder Methode, die du aufrufst.
  3. Es gibt keinen Fall-Through von einem Zweig zum nächsten, daher ist es nicht nötig, dass break.
  4. match gibt einen Wert zurück. Das ist der einzige Grund für ihre Existenz.
  5. Da es sich um einen Ausdruck handelt, ist ein abschließendes ; am allerletzten Ende, genau wie bei Closure-Definitionen.
  6. match ist vollständig. Wenn $var nicht === einer der angegebenen Werte und es gibt kein default, wird ein Fehler ausgelöst.

match Zweige können auch zusammengesetzt und durch Kommas getrennt sein, um ein „ODER“-ähnliches Verhalten zu erzielen, etwa so:

<?php
echo match($operator) {
    '+', '-', '*', '/' => 'Basic arithmetic',
    '%' => 'Modulus',
    '!' => 'Negation',
};

PHP match wurde als modernisierte, nützlichere switch, aber ich bin mir nicht sicher, ob das zutrifft. Ich sehe match eher als ein leistungsfähigeres ternäres Operator.

In der Vergangenheit bin ich oft auf binäre Fälle gestoßen, in denen einer Variablen je nach einer Bedingung einer von zwei Werten zugewiesen werden kann. Die einfachste Art, das zu schreiben, ist meiner Erfahrung nach folgende:

<?php
$display = $user->isAdmin()
    ? $user->name() . ' (admin)'
    : $user->name() . ' (muggle)'
;

Das ist völlig gültiges Programmieren und ziemlich nützlich. Wenn die Logik in der Bedingung oder in einem der beiden Zweige zu komplex ist, um leicht lesbar zu sein, ist das ein Hinweis darauf, dass die Logik in eine eigene Funktion oder Methode ausgelagert werden sollte. Ich habe festgestellt, dass das eine wirklich gute Heuristik für Situationen wie diese ist und zudem zu sehr lesbarem, kompaktem und testbarem Code führt.

Das funktioniert allerdings nur für true/false. match, im Gegensatz dazu, funktioniert für eine beliebige Anzahl von Optionen, hat aber dieselben Anreize, dich zu gut strukturiertem, sauberem Code zu bewegen.

Wenn du komplexere Bedingungen als einfache Identität benötigst, kannst du match auf true:

<?php
$count = get_count();
$size = match(true) {
    $count > 0 && $count <=10 => 'small',
    $count <=50 => 'medium',
    $count >50 => 'huge',
};

Beachte, dass es, da es kein default, führt eine Nichtübereinstimmung (in diesem Fall, wenn $count 0 oder negativ ist) zu einem ausgelösten Fehler führt, anstatt stillschweigend auf null zu setzen und fortzufahren. Das ist gut so, denn Fehler können sich nicht weiterverbreiten und späteren Code beeinträchtigen.

Der RFC zum Match-Express wurde uns freundlicherweise von Ilija Tovilo zur Verfügung gestellt. 

Bleiben Sie auf dem Laufenden

Abonnieren Sie unseren monatlichen Newsletter.

Ihr größtes Werk
steht vor der Tür

Kostenloser Test