PHP match: альтернатива switch с возвратом значения

Раздел: Разработка на PHP

Конструкция 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. Пропуск запятой - синтаксическая ошибка.
- Php javascript css (javascript и css в php)
- Php m3u (создание m3u плейлиста на php)
- Php pid (идентификатор процесса (pid) в php)

Расширенные примеры 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

Конструкция match в PHP - comments

En
Php match (php)