Чем конструкция match отличается от switch в PHP?

Ответ

Конструкция match, появившаяся в PHP 8.0, является более строгим и выразительным аналогом switch. Вот ключевые отличия:

Критерий match switch
Возвращаемое значение Выражение, возвращает результат выбранной ветки. Конструкция, выполняет блок кода. Результат нужно сохранять в отдельную переменную.
Сравнение Строгое (===). Нестрогое (==).
Проверка нескольких значений Нет. Проверяет одно значение. Да, через несколько case.
Обязательность покрытия Должна охватывать все возможные значения или иметь default. Иначе выбрасывается UnhandledMatchError. default не обязателен. Если совпадения нет и default нет, код просто пропускается.
Необходимость break Не нужен. Выполняется только одна ветка. Требуется break, иначе выполнение "проваливается" дальше.
Условия в ветках Поддерживает выражения (можно делать проверки). Только константные значения в case.

Практический пример:

// Использование match (возвращает значение)
$statusCode = 404;
$message = match ($statusCode) {
    200, 201 => 'Успех', // Несколько значений через запятую
    404 => 'Не найдено',
    500 => 'Ошибка сервера',
    default => 'Неизвестный статус', // Обязательно для неохваченных случаев
};
echo $message; // Вывод: Не найдено

// match с условиями
$age = 25;
$category = match (true) {
    $age < 18 => 'Ребёнок',
    $age >= 18 && $age < 65 => 'Взрослый',
    default => 'Пенсионер',
};

// Эквивалент на switch (более многословный)
switch ($statusCode) {
    case 200:
    case 201:
        $message = 'Успех';
        break;
    case 404:
        $message = 'Не найдено';
        break;
    case 500:
        $message = 'Ошибка сервера';
        break;
    default:
        $message = 'Неизвестный статус';
        break; // break здесь тоже нужен для consistency
}

match делает код чище, безопаснее (исключает ошибку пропуска break) и позволяет использовать его прямо в выражениях, например, в аргументах функций или при присваивании.

Ответ 18+ 🔞

А, ну вот, опять про этот ваш match и switch! Сижу тут, вспоминаю, как раньше писали на switch, и просто ёпта, волнение ебать, как же много лишнего кода было. Словно на телеге ехать, когда уже давно есть машина, но ты упорно продолжаешь лошадь кормить.

Смотри, в чём суть. Раньше, чтобы значение куда-то определить, приходилось городить целую манду с ушами под названием switch. И там постоянно можно было накосячить: забудешь break — и всё, привет, выполнение проваливается дальше, как пьяный с лестницы. Сам от себя охуевал, когда баг ищешь, а он вот тут, в этом самом break.

А потом в PHP 8.0 подвезли match. И это, блядь, просто чих-пых тебя в сраку, насколько же всё стало проще и надёжнее. Это не просто замена, это вообще другой уровень.

Давай по пунктам, а то терпения ноль ебать слушать долгие речи.

Главные отличия, если по-простому:

  1. match — это выражение, а switch — конструкция. Это самое важное! match возвращает результат сразу. Не надо заводить временную переменную, мучать её — взял и сразу присвоил куда надо. switch же просто выполняет блок кода, и результат тебе ещё самому сохранять.
  2. Сравнение строгое. match работает только через === (тип и значение). switch — через == (только значение). В switch число 0 и пустая строка '' — одно и то же, что иногда приводит к пиздопроебибным ошибкам. В match такого нет.
  3. Никакого проваливания (fall-through). В match выполнилась одна ветка — и всё, конец истории. Никаких break не нужно, они там даже синтаксически не предусмотрены. Доверия ебать ноль было к этому проваливанию в switch.
  4. Обязательный охват всех случаев. match должен либо все возможные варианты покрыть, либо иметь default. Иначе он тебе выкинет UnhandledMatchError — и правильно сделает, сразу видно, где дыра в логике. switch же может просто молча ничего не сделать, если case не нашёлся и default нет.
  5. В match можно условия пихать. Это вообще ни хуя себе крутая фича. Не просто значение сравнить, а целое выражение проверить. switch на такое не способен.

Примеры, чтобы стало совсем понятно:

Смотри, как теперь красиво и коротко:

// match — всё чётко, сразу в переменную
$statusCode = 404;
$message = match ($statusCode) {
    200, 201 => 'Успех', // Да, несколько значений через запятую!
    404 => 'Не найдено',
    500 => 'Ошибка сервера',
    default => 'Неизвестный статус', // А без default — будет ошибка, если статус не из списка
};
echo $message; // Выведет: Не найдено

// А вот match с условиями — это просто песня!
$age = 25;
$category = match (true) { // Сравниваем с true, а дальше — условия на результат
    $age < 18 => 'Ребёнок',
    $age >= 18 && $age < 65 => 'Взрослый',
    default => 'Пенсионер',
};

А теперь посмотри на этого динозавраswitch. То же самое, но овердохуища кода:

// Эквивалент на switch (смотри, как много воды)
switch ($statusCode) {
    case 200:
    case 201: // Пришлось два case писать, а в match через запятую
        $message = 'Успех';
        break; // Забудешь этот break — всё поломается!
    case 404:
        $message = 'Не найдено';
        break;
    case 500:
        $message = 'Ошибка сервера';
        break;
    default:
        $message = 'Неизвестный статус';
        break; // И тут break, хотя он в default не всегда обязателен, но для порядка ставят
}
// И только теперь $message можно использовать

Короче, хуй с горыmatch выигрывает по всем статьям. Код чище, безопаснее, и его можно прямо внутрь вызова функции засунуть, например. switch оставь для легаси-кода или если тебе реально нужно это самое проваливание (хотя это сомнительное желание). Для всего нового — только match.