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

Перечисления enums в PHP 8.1

5 min read PHP Обновлено 05 Jan 2026
Перечисления enums в PHP 8.1
Перечисления enums в PHP 8.1

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

Кратко

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

Важно: перечисления — это не просто набор констант: у них есть методы, собственные типы (backed enums) и поведение, похожее на объекты.

Что вы найдёте в статье

  • Объяснение базовых и backed enums
  • Примеры использования и проверки типов
  • Когда enums не подходят и альтернативы
  • Чек-листы, критерии приёмки и рекомендации по внедрению

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

Перечисления удобны, когда вы работаете с фиксированным набором связанных значений. Примеры: масти в колоде карт, статусы заказа, тип транспорта. Enums повышают предсказуемость кода и улучшают автодополнение в IDE.

Краткая дефиниция: перечисление — это именованный набор значений, каждое из которых является отдельной сущностью в типовой системе.

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

Базовые (basic) enums в PHP — это перечисления, у которых значения связаны с именами случаев, но не имеют скалярного эквивалента по умолчанию. Пример из документации:

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

Значение указывается как EnumTypeName::EnumField, например:

Season::Winter

Вы можете присвоить такое значение переменной и сравнивать его с другими значениями того же enum:

$favorite = Season::Summer;  
  
if ($favorite == get_current_season()) {  
    echo "It's my favorite season!";  
}

Типизация помогает ограничить параметры и возврат конкретным перечислением, уменьшая количество ошибок:

function get_current_season(): Season  
{  
    $day = date("z");  
  
    if ($day < 59 || $day > 333) return Season::Winter;  
    if ($day < 151) return Season::Spring;  
    if ($day < 243) return Season::Summer;  
    if ($day < 334) return Season::Autumn;  
}

Если функция пытается вернуть не-Season, PHP выдаст TypeError.

Backed enums (перечисления со значениями)

Backed enums — это перечисления, у которых у каждого случая есть скалярное значение (int или string):

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

Тип должен быть объявлен и быть либо int, либо string. Доступ к базовому значению осуществляется через свойство value:

echo Month::Jan->value;

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

var_dump(Month::from(2));

Если значение не соответствует ни одному случаю, метод from выбросит ValueError; есть также tryFrom, который вернёт null вместо ошибки.

Методы перечислений

Enum в PHP может содержать методы — это делает их ближе к классам.

Пример метода для получения количества дней в месяце (без учёта високосного года):

/* Note: no leap-year handling! */  
function daysInMonth(): int {  
    if ($this == Month::Feb) return 28;  
    if (in_array($this, array(Month::Apr, Month::Jun, Month::Sep, Month::Nov))) return 30;  
    return 31;  
}

Внутри метода $this ссылается на конкретный случай перечисления. Также доступны статические методы, например для генерации случайного значения:

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

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

  • Нужна расширяемость в рантайме: enums фиксированы в коде и не предназначены для динамического добавления значений.
  • Значения содержат сложную связанную структуру или много состояний — лучше класс/DTO.
  • Необходима обратная совместимость с системой, где ожидаются примитивы (иногда проще использовать константы).

Контрпример: если у вас управляемый через админку список статусов, который редакторы изменяют без деплоя, enum в коде не подойдёт.

Альтернативы и сравнение

  • Константы класса: простые, но не формируют отдельный тип.
  • Ассоциативные массивы: гибкие, но без типовой безопасности.
  • Классы/Value objects: если нужны поведение и состояние для каждого значения.

Сравнение (кратко):

  • enum — явный тип, безопасный для проверки и подсветки в IDE;
  • константы — простые и гибкие, но не обеспечивают типовой безопасности;
  • класс — больше возможностей, но сложнее, требует больше кода.

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

  • Ментальная модель: enum — это «именованный набор уникальных сущностей», каждая сущность — не просто число/строка, а самостоятельный член множества.
  • Эвристика выбора: если набор фиксирован и логически связан, и вы хотите предотвратить передачу произвольных строк/чисел — используйте enum.

Мини-методология внедрения enums в проект

  1. Идентифицируйте фиксированные наборы (статусы, типы, роли).
  2. Оцените требование к расширяемости.
  3. Создайте enum с полным набором случаев.
  4. Замените магические строки/числа на enum и добавьте типизацию.
  5. Напишите тесты, покрывающие перевод между значениями и методами enum.

Чек-лист по ролям

  • Разработчик: заменить литералы на enum, настроить автодок и IDE-настройки.
  • Технический лидер: согласовать границы enum, определить правила изменения и версионирования.
  • Тестировщик: проверить сериализацию/десериализацию, совместимость с API.

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

  • Все места, где ранее использовались «магические» значения, используют enum или документированное обоснование.
  • Unit-тесты покрывают методы enum и граничные случаи (from/tryFrom).
  • Документация/README проекта обновлены с указанием новых типов.

Примеры тест-кейсов (коротко)

  • Month::from(2) возвращает Month::Feb.
  • Month::tryFrom(99) возвращает null.
  • Метод daysInMonth() возвращает корректное количество дней для каждого месяца (включая 28/29 для февраля, если вы внедрили логику високосного года).

Миграционные заметки

  • При добавлении новых значений enum это breaking change для внешних клиентов, если enum используется в публичном API (особенно для string-backed).
  • Для сериализации используйте value или name сознательно — договоритесь о формате (name даёт понимание, value удобен для хранения в БД).

Важно: перед тем как хранить enum->value в базе, задокументируйте её семантику и поведение при изменениях.

Быстрый справочник (cheat sheet)

  • Объявление базового enum: enum Name { case A; case B; }
  • Backed enum: enum Name: int { case A = 1; }
  • Доступ: Name::A
  • Базовое значение: Name::A->value
  • Конвертация: Name::from(1) или Name::tryFrom(1)
  • Перечисления могут иметь методы и статические фабрики.

Пример простого рабочего сценария

  • UI: выпадающий список статусов формируется из перечисления Status::cases()
  • Backend: API принимает и возвращает либо name, либо value (по соглашению)
  • БД: сохраняет value для компактности, но имеет миграцию на случай изменений

Заключение

Перечисления в PHP 8.1 — значимое дополнение языка: они дают типовую безопасность, улучшают читаемость и упрощают поддержку фиксированных наборов значений. При грамотном применении помогают избежать ошибок, связанных с «магическими» строками и числами. Однако enums не заменят классы там, где нужна динамичность или сложное состояние.

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

  • Используйте enums для фиксированных наборов значений.
  • Выбирайте backed enums, если нужно сохранять скалярные значения.
  • Тщательно продумывайте сериализацию и миграции при использовании enums в API и БД.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

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

Темы Instagram в Reels — как добавлять и тестировать
Социальные сети

Темы Instagram в Reels — как добавлять и тестировать

iTunes не запускается — как исправить
Windows

iTunes не запускается — как исправить

Как добавлять и настраивать виджеты на Android
Android.

Как добавлять и настраивать виджеты на Android

Google Music Frame в Ubuntu — фоновые воспроизведение и управление
Приложения

Google Music Frame в Ubuntu — фоновые воспроизведение и управление

Панель «Изменить последнее действие» в Blender
Blender

Панель «Изменить последнее действие» в Blender

Как оставить Super Thanks на YouTube
YouTube

Как оставить Super Thanks на YouTube