Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11468 глав6256 карточек справочника
Дерево руководства

Глава 209 · От основ к практике

Перечисления PHP: состояния, границы объектов и полный список case

Pure и backed enum от первой задачи до cases(), from() и ограничений модели.

Enum в реальной задаче: допустимые состояния вместо случайных строк

Строка 'paidd' синтаксически допустима и может пройти далеко до ошибки. Enum перечисляет конечный набор состояний, поэтому редактор, анализатор и PHP помогают не передать несуществующее значение.

Ограничить статус заказа и получить подпись для интерфейсаСамостоятельный пример
<?php
enum OrderStatus: string
{
    case New = 'new';
    case Paid = 'paid';
    case Shipped = 'shipped';

    public function label(): string
    {
        return match ($this) {
            self::New => 'Новый',
            self::Paid => 'Оплачен',
            self::Shipped => 'Отправлен',
        };
    }
}

$status = OrderStatus::Paid;
echo $status->value, ': ', $status->label(), "\n";
Ожидаемый результат
paid: Оплачен

Backed enum связывает каждый case с уникальной строкой или целым числом. В базе и JSON можно хранить value, а внутри программы передавать OrderStatus, не произвольную строку. Метод enum держит отображение рядом с допустимыми состояниями.

Отличить недопустимый внешний статус от допустимогоСамостоятельный пример
<?php
enum Delivery: string
{
    case Courier = 'courier';
    case Pickup = 'pickup';
}

foreach (['pickup', 'drone'] as $raw) {
    $delivery = Delivery::tryFrom($raw);
    echo $delivery?->name ?? 'Недопустимо', "\n";
}
Ожидаемый результат
Pickup
Недопустимо

tryFrom() возвращает case или null; это удобно на границе формы/API. from() вместо этого бросает ValueError. У чистого enum без string/int нет from, tryFrom и свойства value.

Pure enum содержит только именованные case и реализует UnitEnum. Backed enum объявляется с типом string или int, каждый case получает уникальное скалярное значение и дополнительно реализует BackedEnum.

Почему enum нельзя расширить наследованием

Enum описывает закрытый набор: когда функция принимает Access, она вправе рассмотреть все его case. Если бы другой enum мог добавить наследника с новым case, существующий исчерпывающий match внезапно стал бы неполным. Поэтому enum final по смыслу, а наследование между перечислениями запрещено.

Проверить, что case — единственный экземпляр своего значенияСамостоятельный пример
<?php
enum Access
{
    case Guest;
    case Admin;
}

$first = Access::Admin;
$second = Access::Admin;

echo $first === $second ? "Один и тот же case\n" : "Разные объекты\n";
echo $first->name, "\n";
Ожидаемый результат
Один и тот же case
Admin

Case ведёт себя как объект и допускает методы, но его нельзя создать через new или клонировать. Каждый объявленный case — один стабильный экземпляр. Свойство name есть у всех enum; value — только у backed enum.

ВозможностьОбычный классEnum
Создать newДаНет; доступны только объявленные case
Состояние в свойствахДаПользовательские свойства запрещены
Конструктор / деструкторДаЗапрещены
НаследованиеОдин родительEnum нельзя наследовать
Интерфейсы и методыДаДа
ТрейтыДаДа, если trait не объявляет свойства
КлонированиеОбычно даЗапрещено
Константы и attributesДаДа

Enum допускает обычные и статические методы, константы и реализацию интерфейсов. Набор magic-методов ограничен: enum не должен превращаться в скрытый контейнер изменяемого состояния. Нельзя самостоятельно реализовать зарезервированные UnitEnum/BackedEnum обычным классом.

Получить полный список case через cases()

Все перечисления автоматически реализуют UnitEnum, чей статический метод cases() возвращает массив всех case. Порядок соответствует исходному объявлению, но если бизнес-порядок важен, закрепите его отдельным правилом и тестом.

Построить варианты select из cases()Самостоятельный пример
<?php
enum PaymentMethod: string
{
    case Card = 'card';
    case Cash = 'cash';
    case Invoice = 'invoice';

    public function label(): string
    {
        return match ($this) {
            self::Card => 'Карта',
            self::Cash => 'Наличные',
            self::Invoice => 'Счёт',
        };
    }
}

foreach (PaymentMethod::cases() as $method) {
    echo $method->value, ' => ', $method->label(), "\n";
}
Ожидаемый результат
card => Карта
cash => Наличные
invoice => Счёт

cases() возвращает плотный массив case в порядке объявления. Для backed enum доступны name и value. Отображаемую подпись лучше хранить в методе или слое локализации, а не показывать техническое имя пользователю.

  • Нельзя переопределить или самостоятельно объявить метод cases() в enum.
  • Результат можно фильтровать для контекста, но исходный enum остаётся полным списком допустимых значений.
  • При сохранении backed value внешние данные восстанавливают через from() или tryFrom().
  • Добавление нового case способно потребовать обновить исчерпывающие match и варианты интерфейса.

Встроенные контракты перечислений также отмечены в карте предопределённых интерфейсов.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.