PHP match: альтернатива switch с возвратом значения
Конструкция match в PHP
Конструкция match появилась в PHP 8.0 как более строгая и выразительная альтернатива switch. В отличие от switch, match возвращает значение, использует строгое сравнение (===) и не требует break. Каждая ветвь (arm) содержит условие и выражение, которое выполняется при совпадении. Если ни одно условие не подошло, выбрасывается исключение UnhandledMatchError, если не указана ветвь default.
Базовый синтаксис:
$result = match ($subject) {
$value1 => $expression1,
$value2 => $expression2,
default => $defaultExpression,
};
обработка php (обработка данных в php)
где $subject - проверяемое выражение, $valueN - значения для сравнения, $expressionN - результат при совпадении. Несколько значений перечисляются через запятую.
Как заменить switch с одним условием?
Простейший случай - проверка одной переменной и возврат строки.
$role = 'admin';
$permission = match ($role) {
'admin' => 'full_access',
'editor' => 'edit_access',
'viewer' => 'view_only',
};
Php learning (обучение php)
Результат: 'full_access'. В switch пришлось бы писать break и присваивать переменную.
Как сопоставить несколько значений в одной ветви?
В match можно объединить несколько вариантов через запятую. Полезно, когда разные значения приводят к одному результату.
$statusCode = 404;
$message = match ($statusCode) {
200, 201 => 'Success',
400, 403, 404 => 'Client Error',
500 => 'Server Error',
};
Php учебник (учебник по php)
При 404 результат - 'Client Error'. В switch пришлось бы использовать fall-through (пропуск break).
Что делать, если ни одно значение не подошло?
Добавляется ветвь default. Без неё при несовпадении выбрасывается исключение.
$animal = 'dog';
$sound = match ($animal) {
'cat' => 'meow',
'dog' => 'bark',
default => 'unknown',
};
Apis php (api на php)
Если $animal равен 'cow', результат - 'unknown', без ошибки.
Как присвоить результат match переменной?
Поскольку match возвращает значение, его можно сразу присвоить переменной или использовать в выражении.
$grade = 85;
$letter = match (true) {
$grade >= 90 => 'A',
$grade >= 80 => 'B',
$grade >= 70 => 'C',
default => 'D',
};
Php categoryid (категории в php)
Здесь match проверяет логические условия - одно из самых мощных применений. Результат - 'B'.
Как использовать match со сложными выражениями?
В условиях могут быть вызовы функций, тернарные операторы или даже вложенные match.
$input = 5;
$output = match ($input) {
1, 2 => 'low',
3, 4, 5 => 'medium',
6, 7, 8, 9 => 'high',
default => match ($input > 10) {
true => 'very high',
false => 'unknown',
},
};
Html javascript php (интеграция html, javascript и php)
При 5 - 'medium', при 15 - 'very high'. Вложенный match обрабатывается, если default не сработал.
Как выбросить исключение при несовпадении?
Если ветвь default не нужна, можно явно выбросить исключение через throw.
$value = 42;
$type = match ($value) {
is_int($value) => 'integer',
is_string($value) => 'string',
default => throw new \InvalidArgumentException('Unsupported type'),
};
Здесь $value - целое число, поэтому срабатывает первая ветвь. Если передать массив, выбросится исключение.
Типичные ошибки и способы их решения
- Непредвиденное исключение UnhandledMatchError. Возникает при отсутствии default, если ни одно условие не совпало. Решение: всегда добавлять default, даже если это throw.
- Сравнение с нестрогим типом. match использует ===, поэтому '1' не совпадет с 1. Для нестрогого сравнения (==) match не подходит, нужно преобразовывать типы или использовать switch.
- Попытка использовать match без присваивания. match - выражение, его результат нужно использовать (присвоить, вернуть, передать в функцию). Просто написать match без присваивания приведёт к ошибке.
- Забытые запятые после ветвей. В match каждая ветвь заканчивается запятой, кроме последней, если нет default. Пропуск запятой - синтаксическая ошибка.
Расширенные примеры match в PHP
Пример 1. Match с объектами и instanceof
class Rectangle { public $width; public $height; }
class Circle { public $radius; }
$shape = new Rectangle();
$shape->width = 10; $shape->height = 20;
$area = match (true) {
$shape instanceof Rectangle => $shape->width * $shape->height,
$shape instanceof Circle => pi() * $shape->radius ** 2,
default => 0,
};
echo $area; // 200
200
Пример 2. Match с enum (PHP 8.1+)
enum HttpStatus: int {
case OK = 200;
case NotFound = 404;
case InternalServerError = 500;
}
$status = HttpStatus::NotFound;
$message = match ($status) {
HttpStatus::OK => 'OK',
HttpStatus::NotFound => 'Not Found',
HttpStatus::InternalServerError => 'Server Error',
};
echo $message; // Not Found
Not Found
Пример 3. Match с анонимными функциями и возвратом замыканий
$operation = 'double';
$handler = match ($operation) {
'increment' => function($x) { return $x + 1; },
'double' => function($x) { return $x * 2; },
'square' => function($x) { return $x * $x; },
};
echo $handler(5); // 10
10
Пример 4. Match в комбинации с array_map и коллекциями
$items = [1, 'hello', true, []];
$types = array_map(fn($item) => match (true) {
is_int($item) => 'int',
is_string($item) => 'string',
is_bool($item) => 'bool',
is_array($item) => 'array',
default => 'unknown',
}, $items);
print_r($types);
Array
(
[0] => int
[1] => string
[2] => bool
[3] => array
)
Пример 5. Вложенный match для классификации чисел
$number = 15;
$result = match (true) {
$number < 0 => 'negative',
$number == 0 => 'zero',
$number > 0 => match (true) {
$number % 2 == 0 => 'positive even',
default => 'positive odd',
},
};
echo "$number: $result"; // 15: positive odd
15: positive odd
Пример 6. Match с union types (PHP 8.0+) и проверкой типов
$input = "42";
$output = match (true) {
is_int($input) => $input * 2,
is_string($input) && is_numeric($input) => (int)$input * 2,
is_string($input) => strtoupper($input),
default => 'unknown type',
};
echo $output; // 84
84