Menu

Выражение match в PHP: match и switch, match(true)

match ($x) { 1, 2 => 'low', default => 'other' } сравнивает значение строго через ===, возвращает результат первой совпавшей ветки и выбрасывает UnhandledMatchError, когда ничего не совпало. match и switch, match(true) и match с перечислениями.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

match ($value) { ... } сравнивает значение со списком веток строго через === и возвращает результат первой совпавшей ветки. Несколько значений могут делить одну ветку, default ловит всё остальное, а если ничего не совпало, PHP выбрасывает UnhandledMatchError.

Обратите внимание на точку с запятой после закрывающей скобки: match это выражение, как 1 + 2, поэтому вся конструкция это одна инструкция присваивания. Каждая ветка записывается как values => result, ветки разделяются запятыми, и запятая после последней ветки допустима.

Несколько значений в одной ветке

Перечислите значения через запятую. Ветка совпадает, если проверяемое значение идентично (===) любому из них.

Возвращать match прямо из функции, как здесь, самый распространённый способ его использования.

match и switch

Одно и то же сопоставление записано двумя способами, а входное значение показывает главное различие, сравнение. switch использует ==, поэтому строка "1" совпадает с case 1. match использует ===, поэтому не совпадает.

matchswitch
Сравнениестрогое ===нестрогое ==
Результатвозвращает значениеинструкция, ничего не возвращает
Проваливаниеникогдада, до break
Несколько значений1, 2 =>подряд case 1: case 2:
Нет совпадениявыбрасывает UnhandledMatchErrorничего не делает
Тело веткиодно выражениелюбое число инструкций

Используйте match, когда превращаете одно значение в другое. Оставляйте switch, когда ветке нужно несколько инструкций или когда смысл как раз в проваливании; оба случая есть на странице про switch.

UnhandledMatchError: когда ни одна ветка не совпала

Без ветки default значение, которое ни с чем не совпало, это ошибка, а не молчаливый null. Это полезно: новый код статуса или опечатка громко падают, а не проскакивают незамеченными.

PHP останавливается с сообщением PHP Fatal error: Uncaught UnhandledMatchError: Unhandled match case of type string. В конфигурации для разработки (с выключенным zend.exception_ignore_args) вместо этого называется значение: Unhandled match case 'XL'. Исправьте это, добавив default => 'other', или перехватите ошибку там, где ожидается неизвестное значение:

match(true) для диапазонов и условий

match сравнивает проверяемое значение с каждой веткой, поэтому, если это значение true, каждая ветка может быть условием. Побеждает первое условие, которое вычисляется в точности в true.

Две детали в этом блоке. Начиная с PHP 8 throw это выражение, поэтому оно может быть результатом ветки. А поскольку сравнение строгое, каждое условие должно возвращать настоящее логическое значение: ветка вроде $name => ... никогда не совпадёт с true, даже если $name непустая строка. Вычисляется только совпавшая ветка, поэтому throw срабатывает лишь для отрицательного возраста.

match с перечислениями

match и перечисления хорошо сочетаются: внутри метода enum match ($this) сопоставляет каждый вариант со значением. Про сами перечисления смотрите enum в PHP.

default здесь нет намеренно. Если кто-то позже добавит пятый вариант, вызов color() для него выбросит ошибку, а не вернёт неправильный цвет.

Несколько инструкций в одной ветке

Ветка содержит одно выражение, поэтому 'save' => { ...; ... } это недопустимый PHP. Вынесите работу в функцию и вызовите её из ветки. Функции несовпавших веток никогда не вызываются.

Поменяйте $format на 'json' или 'xml' и запустите снова.

Часто задаваемые вопросы

Чем match отличается от switch в PHP?

match сравнивает строго через ===, возвращает значение, никогда не проваливается в следующую ветку, принимает несколько значений через запятую в одной ветке и выбрасывает UnhandledMatchError, когда ни одна ветка не совпала. switch сравнивает нестрого через ==, это инструкция, которая ничего не возвращает, проваливается без break и молча ничего не делает, если ни один case не совпал.

Что происходит, когда ни одна ветка match не совпала?

PHP выбрасывает UnhandledMatchError. Добавьте ветку default => ... для всех остальных значений или перехватите ошибку через try { ... } catch (\UnhandledMatchError $e) { ... }.

Как использовать match с условиями вроде "больше чем" в PHP?

Сопоставляйте с true: match (true) { $age < 13 => 'child', $age < 18 => 'teen', default => 'adult' }. Каждая ветка это условие, и побеждает первое, которое в точности равно true.

Может ли ветка match выполнить несколько инструкций?

Нет, каждая ветка это одно выражение. Поместите инструкции в функцию или метод и вызовите их из ветки, например 'export' => exportCsv($rows).

В какой версии PHP появился match?

В PHP 8.0. В PHP 7 ту же логику пишут через switch или поиск по массиву вроде $labels[$status] ?? 'Unknown'.

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ