match ($value) { ... } porównuje wartość z listą ramion ścisłym === i zwraca wynik pierwszego pasującego ramienia. Kilka wartości może dzielić jedno ramię, default łapie resztę, a jeśli nic nie pasuje, PHP rzuca UnhandledMatchError.
Zwróć uwagę na średnik po nawiasie zamykającym: match jest wyrażeniem, jak 1 + 2, więc całość to jedna instrukcja przypisania. Każde ramię ma postać values => result, ramiona rozdziela się przecinkami, a przecinek po ostatnim ramieniu jest dozwolony.
Kilka wartości w jednym ramieniu
Wypisz wartości po przecinku. Ramię pasuje, jeśli wartość badana jest identyczna (===) z którąkolwiek z nich.
Zwracanie match bezpośrednio z funkcji, jak tutaj, to najczęstszy sposób jego użycia.
match vs switch
To samo mapowanie zapisane na oba sposoby, z jednym wejściem, które pokazuje największą różnicę: porównanie. switch używa ==, więc string "1" pasuje do case 1. match używa ===, więc nie pasuje.
match | switch | |
|---|---|---|
| Porównanie | ścisłe === | luźne == |
| Wynik | zwraca wartość | instrukcja, nic nie zwraca |
| Przechodzenie | nigdy | tak, aż do break |
| Kilka wartości | 1, 2 => | ułożone case 1: case 2: |
| Brak dopasowania | rzuca UnhandledMatchError | nic nie robi |
| Treść gałęzi | jedno wyrażenie | dowolna liczba instrukcji |
Używaj match, gdy zamieniasz jedną wartość na inną. Zostań przy switch, gdy gałąź potrzebuje kilku instrukcji albo gdy chodzi właśnie o przechodzenie; strona o switch pokazuje oba przypadki.
UnhandledMatchError: gdy żadne ramię nie pasuje
Bez ramienia default wartość, która do niczego nie pasuje, jest błędem, a nie cichym null. To zaleta: nowy kod statusu albo literówka kończą się głośnym błędem, zamiast się prześlizgnąć.
PHP zatrzymuje się z komunikatem PHP Fatal error: Uncaught UnhandledMatchError: Unhandled match case of type string. Środowisko deweloperskie (z wyłączonym zend.exception_ignore_args) podaje zamiast tego wartość: Unhandled match case 'XL'. Napraw to, dodając default => 'other', albo przechwytując błąd tam, gdzie spodziewasz się nieznanej wartości:
match(true) dla zakresów i warunków
match porównuje wartość badaną z każdym ramieniem, więc jeśli wartością badaną jest true, każde ramię może być warunkiem. Wygrywa pierwszy warunek, który daje dokładnie true.
Dwa szczegóły w tym bloku. throw jest wyrażeniem od PHP 8, więc może być wynikiem ramienia. A ponieważ porównanie jest ścisłe, każdy warunek musi zwracać prawdziwą wartość logiczną: ramię w rodzaju $name => ... nigdy nie pasuje do true, nawet gdy $name jest niepustym stringiem. Obliczane jest tylko pasujące ramię, więc throw wykonuje się wyłącznie dla ujemnego wieku.
match z enumami
match i enumy dobrze do siebie pasują: w metodzie enuma match ($this) przypisuje każdemu przypadkowi wartość. O samych enumach przeczytasz na stronie enumy w PHP.
Celowo nie ma tu default. Jeśli ktoś później doda piąty przypadek, wywołanie na nim color() rzuci błąd zamiast zwrócić zły kolor.
Kilka instrukcji w jednym ramieniu
Ramię zawiera jedno wyrażenie, więc 'save' => { ...; ... } nie jest poprawnym PHP. Przenieś pracę do funkcji i wywołaj ją z ramienia. Funkcje z ramion, które nie pasują, nigdy nie są wywoływane.
Zmień $format na 'json' albo 'xml' i uruchom ponownie.
Najczęściej zadawane pytania
Czym różni się match od switch w PHP?
match porównuje ścisłym ===, zwraca wartość, nigdy nie przechodzi do następnego ramienia, przyjmuje kilka wartości rozdzielonych przecinkami w jednym ramieniu i rzuca UnhandledMatchError, gdy żadne ramię nie pasuje. switch porównuje luźnym ==, jest instrukcją, która nic nie zwraca, przechodzi dalej bez break i po cichu nic nie robi, gdy żaden case nie pasuje.
Co się dzieje, gdy żadne ramię nie pasuje w wyrażeniu match w PHP?
PHP rzuca UnhandledMatchError. Dodaj ramię default => ..., które obsłuży każdą inną wartość, albo przechwyć błąd przez try { ... } catch (\UnhandledMatchError $e) { ... }.
Jak użyć match z warunkami typu większe niż w PHP?
Dopasuj do true: match (true) { $age < 13 => 'child', $age < 18 => 'teen', default => 'adult' }. Każde ramię jest warunkiem, a wygrywa pierwsze, które daje dokładnie true.
Czy ramię match może wykonać kilka instrukcji w PHP?
Nie, każde ramię to jedno wyrażenie. Umieść instrukcje w funkcji lub metodzie i wywołaj ją z ramienia, na przykład 'export' => exportCsv($rows).
W której wersji PHP pojawiło się match?
W PHP 8.0. W PHP 7 ta sama logika wymaga instrukcji switch albo wyszukania w tablicy, na przykład $labels[$status] ?? 'Unknown'.