Перечисления PHP 8.1: статусы без произвольных строк
Описываем статусы задачи через enum PHP 8.1 и обрабатываем неизвестные значения на входе.
- Входное значениеПолучаем строку или число нужного типа
- tryFromСопоставляем с допустимым значением enum
- РезультатИспользуем статус или обрабатываем неизвестное значение
Одна опечатка — и вместо pending в базе появляется pendng. Строки удобны для хранения, но допустимые статусы лучше описать в одном месте. В PHP 8.1 для этого есть перечисления. Backed enum связывает каждый вариант со строкой или числом, а tryFrom позволяет разобрать ввод без необработанного исключения.
Описываем допустимые состояния
<?php
enum JobStatus: string {
case Pending = 'pending';
case Done = 'done';
}
$status = JobStatus::tryFrom($input);
if ($status === null) {
throw new InvalidArgumentException('Неизвестный статус');
}
$databaseValue = $status->value;Предполагается, что input уже получен как строка из проверенного поля запроса. tryFrom возвращает null для неизвестного значения, позволяя сформировать понятную ошибку. Метод from подходит, когда отсутствие соответствия действительно должно приводить к исключению. Случай перечисления и его строковое value — разные значения.
Граница с базой данных
Перечисление в приложении не заменяет ограничения базы. Другой клиент может записать произвольную строку, если схема её допускает. Согласуйте допустимые значения, миграции и обработку старых записей. Не переименовывайте сохраняемое значение без плана перехода: исторические данные не изменятся вслед за PHP-кодом.
Набор вариантов описывает допустимые состояния, но не разрешённые переходы. Возможность перейти из done обратно в pending определяется отдельным правилом. Это правило должно учитывать права пользователя, состояние задачи и требования к журналированию изменений.
Проверяем границы
Проверьте каждый известный статус, пустую строку и незнакомое значение. Посмотрите, как enum передаётся в JSON и в драйвер базы: снаружи нужен ожидаемый формат, внутри — типизированный вариант. И проверьте версию PHP: на 8.0 перечисление из примера не заработает, оно требует 8.1.
