Гид по технологиям

Перечисления (Enums) в PHP 8.1

4 min read PHP Обновлено 31 Dec 2025
Перечисления в PHP 8.1 — быстрое руководство
Перечисления в PHP 8.1 — быстрое руководство

Перечисления в PHP 8.1 позволяют описать ограниченный набор значений как отдельный тип. Они усиливают проверку типов, упрощают поддержку кода и позволяют добавлять методы и статические фабрики. Используйте базовые enums для именованных вариантов и поддерживаемые (backed) enums, если нужно связать каждое значение со строкой или целым числом.

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

Что делают перечисления

Перечисления полезны, когда нужно работать с фиксированным набором связанных значений. Они подходят для представления мастей карт, типов транспортных средств или статусов заказа. В PHP перечисления имеют черты классов: их можно использовать в подсказках типов (type hinting), добавлять методы и статические вспомогательные функции.

Определение термина

  • Перечисление (enum) — именованный тип, значение которого ограничено фиксированным набором кейсов. Кратко: enum = ограниченный набор значений, доступных в коде.

Базовые перечисления

Базовые enums в PHP не имеют связанного скалярного значения. Их значения — имена кейсов.

enum Season
{
    case Spring;
    case Summer;
    case Autumn;
    case Winter;
}

Обращение к конкретному значению выполняется через синтаксис EnumTypeName::CaseName:

// Ссылка на значение
$w = Season::Winter;
// Проверка
$favourite = Season::Summer;
if ($favourite == get_current_season()) {
    echo "It's my favorite season!";
}

Подсказки типов позволят ограничить параметры и возвращаемые значения конкретным перечислением. Это уменьшает количество ошибок и делает код предсказуемее:

function get_current_season(): Season
{
    $day = date("z"); // номер дня в году, 0..365

    if ($day < 59 || $day > 333) return Season::Winter;
    if ($day < 151) return Season::Spring;
    if ($day < 243) return Season::Summer;
    return Season::Autumn;
}

Если функция вернёт не значение Season, PHP выбросит TypeError.

Поддерживаемые перечисления

Backed enums — это перечисления, у которых у каждого кейса есть связанное скалярное значение: int или string. Тип нужно объявить явно.

enum Month: int
{
    case Jan = 1;
    case Feb = 2;
    // ...
}

Доступ к базовому значению осуществляется через свойство value:

echo Month::Jan->value; // выведет 1

Есть удобный статический метод from для преобразования скалярного значения в enum:

var_dump(Month::from(2)); // вернёт Month::Feb или выбросит ValueError

Используйте backed enums, когда данные приходят извне (JSON, БД, HTTP) и нужно хранить сопоставимое значение.

Методы в перечислениях

Перечисления могут содержать методы и поведение. Внутри метода можно использовать $this, как в объекте. Это полезно для вычислений, связанных с конкретным кейсом.

enum Month: int
{
    case Jan = 1;
    case Feb = 2;
    case Mar = 3;
    case Apr = 4;
    case May = 5;
    case Jun = 6;
    case Jul = 7;
    case Aug = 8;
    case Sep = 9;
    case Oct = 10;
    case Nov = 11;
    case Dec = 12;

    /* Внимание: обработка високосного года не реализована */
    public function daysInMonth(): int
    {
        if ($this == Month::Feb) return 28;
        if (in_array($this, [Month::Apr, Month::Jun, Month::Sep, Month::Nov])) return 30;
        return 31;
    }

    public static function random(): Month
    {
        return Month::from(rand(1, count(Month::cases())));
    }
}

Статические методы полезны для фабрик, генерации случайного значения или валидации.

Когда перечисления не подходят

Important

  • Если набор значений меняется часто и динамически (например, администратор добавляет варианты через UI), enum не подойдёт — лучше использовать запись в БД или конфиг.
  • Когда к каждому значению нужно хранить большое количество связанных данных (много полей), удобнее использовать класс записи/сущность или Value Object.
  • Если требуется множественное сочетание флагов (биты), рассмотрите битовые флаги или отдельные объекты, а не enum.

Альтернативные подходы

  • Константы в классе (class constants) — если нужна простая группировка без методов.
  • Value Object — когда требуется поведение и связанные данные на экземпляр.
  • Таблица в базе данных — если набор изменяем пользователем.
  • Битовые маски — для множества флагов, где значения комбинируются.

Ментальные модели и эвристики

  • Enum = именованная группа вариантов. Если можно перечислить все варианты заранее — используйте enum.
  • Backed enum = enum, который сериализуется / маппится в БД или в API.
  • Методы в enum = поведение, относящееся только к конкретному варианту.

Факто-бокс

  • Минимальная версия PHP с поддержкой: 8.1
  • Поддерживаемые типы для backed enum: int, string
  • Полезные методы: ->value, ::from(), ::cases()

Чек-лист для ролей

Разработчик

  • Решить, статичен ли набор значений.
  • Выбрать базовый или backed enum.
  • Добавить unit-тесты для методов enum.
  • Использовать подсказки типов в сигнатурах функций.

Код-ревьювер

  • Проверить, не скрывает ли enum бизнес-логику, которую лучше вынести в сервис.
  • Убедиться, что from обрабатывает неверные входные данные.

Оператор/DevOps

  • Проверить минимальную версию PHP в окружениях: >= 8.1.
  • Убедиться, что миграции и сериализация совместимы с сохранёнными значениями.

Критерии приёмки

  • Unit-тесты покрывают все кейсы enums и методы.
  • Для backed enum проверки на корректную сериализацию/десериализацию в БД.
  • Функции с hint: возвращают только значения enum, иначе TypeError.

Чит-карта и примеры

Быстрые сниппеты для часто встречающихся задач:

// Перебор всех кейсов
foreach (Month::cases() as $m) {
    echo $m->value . " - " . $m->name . "\n";
}

// Конвертация из строки/числа
try {
    $m = Month::from(12);
} catch (ValueError $e) {
    // обработка некорректного значения
}

// Использование в подсказках типов
function handleMonth(Month $month): void {
    // ...
}

Совместимость и миграция

  • Требуется PHP 8.1+. Для старых версий используйте класс-константы или пакеты-полифилы, но поведение будет ограничено.
  • При миграции данных в БД заранее проверьте соответствие значений (для backed enum).
  • Если сериализация JSON используется в API, документируйте, что приходит: имя кейса или его value.

Короткое руководство по дизайну

  1. Выясните, статичен ли набор значений.
  2. Если да, решите: нужен ли скалярный эквивалент для хранения или передачи.
  3. Используйте методы enum для логики, которая зависит только от значения.
  4. При необходимости добавьте статические фабрики и валидаторы.

Краткое резюме

Перечисления в PHP 8.1 упрощают работу со статичными наборами значений, повышают читаемость и безопасность типов. Backed enums удобны для сериализации и хранения, методы внутри enum позволяют инкапсулировать поведение, связанное с конкретным вариантом. Выбирайте enum, когда набор значений стабилен и заранее известен.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Вторая временная зона в Google Календаре
Продуктивность

Вторая временная зона в Google Календаре

Как изменить первый день недели в Google Календаре
Инструкции

Как изменить первый день недели в Google Календаре

Отключить события из Gmail в Google Календаре
Google Календарь

Отключить события из Gmail в Google Календаре

Включить тёмный режим в Google Календаре
Руководство

Включить тёмный режим в Google Календаре

Тайм‑блокинг коммуникаций для продуктивной работы
Продуктивность

Тайм‑блокинг коммуникаций для продуктивной работы

Как добавить праздники в Google Calendar и Outlook
Календарь

Как добавить праздники в Google Calendar и Outlook