Ausblick auf PHP 8: Teil 2

PHP 8.0-Features im Fokus: match () Expressions
Keine Kommentare

Das Release von PHP 8 steht kurz bevor und mit ihm eine Reihe von Verbesserungen, neuen Funktionen und die generelle Überarbeitung, um die weit verbreitete serverseitige Websprache noch besser zu machen. In dieser Serie wollen wir darauf eingehen, was Sie über PHP 8 wissen sollten.

Der Countdown zum großen Release von PHP 8 ist bereits angebrochen. Die lang erwartete neue Version enthält eine ganze Reihe von neuen Funktionen und Verbesserungen, die den Entwicklern das Leben leichter machen sollen. In dieser Serie werfen wir einen Blick auf diese Neuerungen und was sie für die Nutzer bedeuten. Im zweiten Teil beschäftigen wir uns mit den neuen match() Expressions.

PHP hat schon seit Ewigkeiten ein switch-Statement, das auf demselben Konstrukt in C modelliert wurde:

<?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;

Der klassische switch erledigt zwar seinen Job, hat aber gleichzeitig auch eine Reihe von Schwächen. Die meisten neueren Sprachen wie Go oder Rust haben sich für robustere, weniger fehleranfällige Strukturen entschieden, die viele verschiedene Namen tragen. Über eine solche verfügt nun auch PHP.

Hier kommt match. Im Gegensatz zu switch ist match eine Expression. Das bedeutet, es bezieht sich auf einen Wert. So wie hier:

<?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;

Dabei sind folgende Punkte zu beachten:

  1. Bei switch wird jeder case durch Loose Equality == verglichen. Bei match wird jeder Branch durch Strict Equality === verglichen. Das bedeutet, dass die Typen auch matchen müssen.
  2. Jeder Branch von match ist nur eine einzelne Expression. Keine Multi-Line-Statements, einfach nur eine einzelne Expression, die bewertet wird. Falls eine komplexe Logik benötigt wird, macht man eine Funktion oder Methode daraus, die aufgerufen wird.
  3. Es gibt kein Fall-Through von einem Branch in den nächsten. Es wird also kein break benötigt.
  4. match gibt einen Wert aus. Das ist der ganze Sinn seiner Existenz.
  5. Da es sich um eine Expression handelt, muss ein ; am Ende stehen, ähnlich wie bei Abschlussdefinitionen.
  6. matchist ausführlich. Wenn $var nicht === einer der angegebenen Werte ist und es keinen default gibt, wird ein Fehler ausgeworfen.

 

match-Branches können aber auch zusammengesetzt und Komma-getrennt sein im Falle von or-ähnlichem Verhalten. So wie hier:

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

match wurde als modernisiertes, nützlicheres switch angepriesen, aber ich bin mir nicht sicher, ob das so richtig ist. Ich finde, match ist eher eine mächtigere Ternary.

In der Vergangenheit hatte ich oft mit Binary Cases zu tun, in denen eine Variable einem von zwei Werten zugeordnet werden konnte, abhängig von irgendeiner Bedingung. Der leichteste Weg, das zu beschreiben, ist Folgender:

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

Das ist absolut valider Code und ziemlich nützlich. Falls die Logik in der Bedingung oder in einem der Branches zu komplex ist, um sie einfach zu lesen, ist das ein Hinweis darauf, dass die Logik aus ihrer eigenen Funktion oder Logik heraus umgearbeitet werden sollte. Ich empfinde das als eine gute Heuristik für solche Situationen und es führt zu leicht lesbarem, testbarem und kompaktem Code.

Das Ganze funktioniert aber nur für true/false. Im Gegensatz dazu funktioniert match für jede Menge Möglichkeiten und hat ebenfalls die Motivation, den Programmierer zu gut geschriebenen, sauberen Code zu bringen.

Falls man komplexere Bedingungen als eine einfache Identity benötigt, kann man match auf true anwenden:

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

Hier gilt es zu beachten, dass ein non-match (hier bspw. falls $count 0 oder negativ ist) einen Fehler werfen wird anstatt stillschweigend zu nullen und weiterzumachen, da kein default festgelegt ist. Das ist insofern gut, weil Fehler späteren Code nicht weiter unnötig belasten.

Der Match-Expression RFC wurde von Ilija Tovilo eingebracht.

Nächste Woche wenden wir uns einem weiteren Feature zu, das mit 8.0 endlich fertiggestellt wurde, nachdem die Arbeit daran bereits in Version 7.4 begann: Weak Maps.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Abonnieren
Benachrichtige mich bei
guest
0 Comments
Inline Feedbacks
View all comments
X
- Gib Deinen Standort ein -
- or -