(PHP 8)
Выражение match
выбирает ветвь вычисления
на основе проверки, которая показывает, идентично ли значение условного выражения
значению входного условного выражения.
Аналогично инструкции switch
выражение
match
принимает на вход выражение, которое сравнивается
с набором альтернатив. В отличие от инструкции switch
,
выражение сопоставления оценивает значение в стиле, который больше похож на тернарный оператор.
Выражение выполняет строгое сравнение ===
, а не слабую проверку на равенство ==
,
как это делает инструкция switch
.
Выражения сопоставления доступны с PHP 8.0.0.
Пример #1 Структура выражения match
<?php
$return_value = match (subject_expression) {
single_conditional_expression => return_expression,
conditional_expression1, conditional_expression2 => return_expression,
};
?>
Пример #2 Базовый пример сопоставления значений в выражении match
<?php
$food = 'cake';
$return_value = match ($food) {
'apple' => 'На столе лежит яблоко',
'banana' => 'На столе лежит банан',
'cake' => 'На столе стоит торт',
};
var_dump($return_value);
?>
Результат выполнения приведённого примера:
string(35) "На столе стоит торт"
Пример #3 Пример сопоставления значений в выражении match
с операторами сравнения
<?php
$age = 18;
$output = match (true) {
$age < 2 => "Младенец",
$age < 13 => "Ребёнок",
$age <= 19 => "Подросток",
$age >= 40 => "Взрослый",
$age > 19 => "Молодой человек",
};
var_dump($output);
?>
Результат выполнения приведённого примера:
string(8) "Подросток"
Замечание: Результат выражения
match
использовать не обязательно.
Замечание: Выражение
match
должно завершаться точкой с запятой;
, если записывается как отдельное выражение.
Выражение match
похоже на инструкцию
switch
, за исключением отдельных ключевых отличий:
match
значения сравниваются строго — ===
match
возвращает значение
match
выполнение кода не переходит к следующей
ветви сопоставления значений после первого совпадения значений,
в отличие от провалов к следующему случаю в инструкции switch
match
должно быть исчерпывающим
Как и инструкциях switch
, в выражениях match
ветви сопоставления значений выполняются одна за другой.
В начале никакой код не выполняется. Условные выражения оцениваются, только если
предыдущие условные выражения не соответствуют входному выражению.
Выражение match вычислит только то выражение возврата, которое соответствует
условному выражению, значение которого совпало.
Приведём пример:
<?php
$result = match ($x) {
foo() => 'value',
$this->bar() => ..., // Метод $this->bar() не вызывается, если значение возврата функции foo() === $x
$this->baz => beep(), // Функция beep() выполнится, если только входное выражение $x === $this->baz
// и т. д.
};
?>
Ветвям сопоставления значений в выражении match
разрешается содержать
множественные выражения, разделённые запятыми.
Множественные выражения проверяются по условию логического ИЛИ и представляют короткую запись
для множественных ветвей сопоставления значений с одним и тем выражением в правой части.
<?php
$result = match ($x) {
// Эта ветвь сопоставления значений:
$a, $b, $c => 5,
// ...эквивалентна следующему набору из трёх ветвей сопоставления:
$a => 5,
$b => 5,
$c => 5,
};
?>
Выражение сопоставления управляет случаями по умолчанию через шаблон default
.
Управление переходит к шаблону по умолчанию при несовпадении значений в предыдущих ветвях сопоставления.
Например:
<?php
$expressionResult = match ($condition) {
1, 2 => foo(),
3, 4 => bar(),
default => baz(),
};
?>
Замечание: Многократные шаблоны default вызовут ошибку уровня
E_FATAL_ERROR
.
Выражение match
должно быть исчерпывающим.
Выражение выбрасывает исключение UnhandledMatchError,
если входное выражение не обработала ни одна ветвь сопоставления.
Пример #4 Пример необработанного выражения match
<?php
$condition = 5;
try {
match ($condition) {
1, 2 => foo(),
3, 4 => bar(),
};
} catch (\UnhandledMatchError $e) {
var_dump($e);
}
?>
Результат выполнения приведённого примера:
object(UnhandledMatchError)#1 (7) { ["message":protected]=> string(33) "Unhandled match value of type int" ["string":"Error":private]=> string(0) "" ["code":protected]=> int(0) ["file":protected]=> string(9) "/in/ICgGK" ["line":protected]=> int(6) ["trace":"Error":private]=> array(0) { } ["previous":"Error":private]=> NULL }
Выражение match
умеет обрабатывать случаи с нетождественными условиями.
Для этого входное выражении указывают как значение true
.
Пример #5 Пример обобщения выражения match для ветвления на основе целочисленных диапазонов
<?php
$age = 23;
$result = match (true) {
$age >= 65 => 'пожилой',
$age >= 25 => 'взрослый',
$age >= 18 => 'совершеннолетний',
default => 'ребёнок',
};
var_dump($result);
?>
Результат выполнения приведённого примера:
string(11) "совершеннолетний"
Пример #6 Пример обобщения выражения match для выбора ветви вычисления на основе содержимого строки
<?php
$text = 'Bienvenue chez nous';
$result = match (true) {
str_contains($text, 'Welcome') || str_contains($text, 'Hello') => 'en',
str_contains($text, 'Bienvenue') || str_contains($text, 'Bonjour') => 'fr',
// ...
};
var_dump($result);
?>
Результат выполнения приведённого примера:
string(2) "fr"