Enums в PHP: как использовать перечисления с примерами кода

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Enums в PHP: от хаоса к порядку

Вы когда-нибудь писали код, в котором статус заказа хранится как строка 'new', 'paid', 'shipped'? А потом ловили баги из-за опечатки 'shippped'? Или передавали в функцию getOrderByStatus('Active'), а там ждали 'active'? Знакомо? Тогда эта статья для вас.

Долгое время в PHP не было родных перечислений (enums). Разработчики изворачивались: использовали константы классов, массивы, даже комментарии-заглушки. Но с выходом PHP 8.1 всё изменилось. Теперь у нас есть полноценные перечисления PHP — мощный инструмент, который делает код чище, безопаснее и понятнее.

В этом руководстве мы разберём enums PHP от А до Я: от базового синтаксиса до продвинутых приёмов. Вы узнаете, как создавать перечисления, работать с ними, сравнивать и использовать в реальных проектах. Поехали!

Что такое Enum в PHP?

Enum (enumeration) — это тип данных, который ограничен набором предопределённых значений. Простыми словами: вы определяете список возможных вариантов, и переменная может принять только один из них. Никаких случайных строк, никаких непроверенных значений.

В PHP 8.1 перечисления реализованы как специальные классы. Каждое значение — это объект, а не просто константа. Это даёт массу преимуществ:

  • Строгая типизация — компилятор не пропустит 'pending' вместо Status::Pending
  • Безопасность — никаких случайных опечаток
  • Читаемость — код говорит сам за себя
  • IDE-поддержка — автодополнение работает на ура

Синтаксис Enum в PHP

Создать перечисление в PHP просто. Используйте ключевое слово enum:

<?php

enum OrderStatus
{
    case New;
    case Pending;
    case Processing;
    case Shipped;
    case Delivered;
    case Cancelled;
}

Теперь мы можем использовать OrderStatus как тип:

<?php

function updateOrderStatus(OrderStatus $status): void
{
    // Обработка статуса
}

// Передаём значение:
updateOrderStatus(OrderStatus::Shipped);

Попробуйте передать строку 'shipped' — PHP выдаст ошибку типа. Это и есть магия enum в PHP.

Enum с бэкингом (Backed Enums)

Часто нам нужно связать каждый кейс с конкретным значением — например, числом или строкой для базы данных. В PHP это называется backed enum:

<?php

enum OrderStatus: string
{
    case New = 'new';
    case Pending = 'pending';
    case Processing = 'processing';
    case Shipped = 'shipped';
    case Delivered = 'delivered';
    case Cancelled = 'cancelled';
}

Теперь каждый кейс имеет строковое значение. Вы можете получить его через свойство value:

<?php

$status = OrderStatus::Shipped;
echo $status->value; // 'shipped'

А можно создать кейс из значения обратно:

<?php

$status = OrderStatus::from('shipped');
echo $status->name; // 'Shipped'

Метод from() выбросит исключение, если значение не найдено. Если хотите получить null — используйте tryFrom().

Методы в Enum: поведение внутри перечислений

Одна из крутых фич PHP enum — возможность добавлять методы прямо внутрь перечисления. Это превращает enum из простого списка констант в полноценный объект с логикой.

<?php

enum OrderStatus: string
{
    case New = 'new';
    case Pending = 'pending';
    case Processing = 'processing';
    case Shipped = 'shipped';
    case Delivered = 'delivered';
    case Cancelled = 'cancelled';

    public function label(): string
    {
        return match($this) {
            self::New => 'Новый заказ',
            self::Pending => 'Ожидает оплаты',
            self::Processing => 'В обработке',
            self::Shipped => 'Отправлен',
            self::Delivered => 'Доставлен',
            self::Cancelled => 'Отменён',
        };
    }

    public function isFinal(): bool
    {
        return in_array($this, [self::Delivered, self::Cancelled]);
    }
}

Использование:

<?php

$status = OrderStatus::Shipped;
echo $status->label(); // 'Отправлен'
echo $status->isFinal(); // false

Теперь вся логика, связанная со статусами, живёт внутри самого enum. Никаких разбросанных switch-case по всему коду!

Сравнение Enum в PHP

Так как каждый кейс enum — это объект, сравнение работает через ===:

<?php

$status = OrderStatus::Shipped;

if ($status === OrderStatus::Shipped) {
    echo 'Заказ отправлен';
}

// Работает и с match:
$message = match($status) {
    OrderStatus::New => 'Новый заказ',
    OrderStatus::Cancelled => 'Отменён',
    default => 'Другой статус',
};

Важно: два разных enum-типа (например, OrderStatus и PaymentStatus) никогда не будут равны, даже если у них одинаковые имена кейсов. Это защита от случайных ошибок.

Enum и switch-case: классика

Конечно, старый добрый switch тоже работает:

<?php

function getStatusColor(OrderStatus $status): string
{
    switch ($status) {
        case OrderStatus::New:
            return 'blue';
        case OrderStatus::Pending:
            return 'yellow';
        case OrderStatus::Processing:
            return 'orange';
        case OrderStatus::Shipped:
            return 'purple';
        case OrderStatus::Delivered:
            return 'green';
        case OrderStatus::Cancelled:
            return 'red';
    }
}

Но я рекомендую match — он короче и безопаснее (PHP проверит, что вы обработали все кейсы, если включите строгие типы).

Перечисление всех значений Enum

Иногда нужно получить список всех возможных значений. Для этого есть статический метод cases():

<?php

$allStatuses = OrderStatus::cases();

foreach ($allStatuses as $status) {
    echo $status->name . ': ' . $status->value . PHP_EOL;
}

Вывод:

New: new
Pending: pending
Processing: processing
Shipped: shipped
Delivered: delivered
Cancelled: cancelled

Это удобно для заполнения выпадающих списков, генерации документации или валидации.

Enum в реальных проектах

Давайте посмотрим, как enum php применяется в типичных задачах.

Пример 1: Статусы заказа

Блоги

Рекомендаций по книгам