главная/PHP оператор match
PHP match

PHP оператор match

Match — это современная, более строгая и выразительная альтернатива switch. В PHP с версии 8.0

Основные преимущества:

  1. Возвращает значение — это выражение, а не оператор.
  2. Строгое сравнение (===) — в отличие от switch.
  3. Не требует break — исключает распространённые ошибки.
  4. Компактный синтаксис — меньше “шумного” кода.
  5. Может работать с несколькими значениями в одной ветке.

Удобен при:

  • простой маршрутизации входящих данных;
  • замене длинных if/elseif цепочек;
  • преобразовании значений одной формы в другую;
  • выборе обработчиков по типу/статусу.
$result = match ($value) {
    1 => "one",
    2 => "two",
    default => "unknown",
};

Пример 1: замена switch

Было:

switch ($status) {
    case 'new':
        $text = 'Новая заявка';
        break;
    case 'processing':
        $text = 'В обработке';
        break;
    default:
        $text = 'Неизвестно';
}

Стало:

$text = match ($status) {
    'new' => 'Новая заявка',
    'processing' => 'В обработке',
    default => 'Неизвестно',
};

Пример 2: строгие сравнения

$value = "1";

$result = match ($value) {
    1 => "число",
    "1" => "строка",
};

// $result = "строка"

switch бы выбрал 1 => «число» из-за нестрогого сравнения.

Пример 3: несколько значений в одной ветке

$type = "jpg";

$category = match ($type) {
    'jpg', 'png', 'gif' => 'image',
    'mp4', 'mov' => 'video',
    default => 'unknown',
};

Пример 4: выполнение логики в блоке

Можно возвращать результат выражения:

$price = 150;

$discount = match (true) {
    $price < 100 => 0,
    $price < 200 => 10,
    default => 20,
};

Пример 5: match без значения (аналог switch(true))

$result = match (true) {
    $a > 10 => 'больше 10',
    $a > 5  => 'больше 5',
    default => 'меньше или равно 5',
};

Пример 6: выброс исключения

$action = match ($route) {
    'home' => fn() => showHome(),
    'login' => fn() => showLogin(),
    default => throw new Exception("Маршрут не найден"),
};

Пример 7: Карта констант/enum (идеально для PHP 8.1 enum)

enum Role { case USER; case ADMIN; }

function label(Role $role): string
{
    return match ($role) {
        Role::USER  => 'Пользователь',
        Role::ADMIN => 'Администратор',
    };
}

match лучше не использовать, когда требуется сложная логика в ветках (много кода, побочные эффекты), когда нужно поведение switch с fallthrough*, когда сравнение должно быть нестрогим ==, когда порядок проверки условий важен или зависит от вычислений, а также когда результат не нужно возвращать — в таких случаях обычные if/elseif или switch будут проще и понятнее.

*Fallthrough — это поведение оператора switch, при котором выполнение проваливается из одного case в следующий, если не стоит break.

switch ($value) {
    case 1:
        echo "one";
        // нет break — происходит fallthrough
    case 2:
        echo "two";
        break;
}

Если $value = 1, то выведет:

one
two

То есть после совпадения case 1 управление продолжит выполняться в case 2.

В match такое невозможно: каждая ветка — отдельное выражение без перехода на следующую.