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

Дерево руководства
Глава 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 по смыслу, а наследование между перечислениями запрещено.
<?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. Порядок соответствует исходному объявлению, но если бизнес-порядок важен, закрепите его отдельным правилом и тестом.
<?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. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


