Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Senior Enums

Як безпечно приймати значення enum ззовні і чим from відрізняється від tryFrom?

Значення з запиту, бази, черги чи стороннього API - це рядок або число, яке може не відповідати жодному варіанту.

  • Status::from($value) - повертає варіант або кидає ValueError, якщо такого немає.
  • Status::tryFrom($value) - повертає варіант або null.
$status = Status::tryFrom($request->input('status'))
    ?? throw ValidationException::withMessages(['status' => 'Невідомий статус']);

Коли що:

  • from - коли невідоме значення означає баг чи пошкоджені дані, і правильна реакція - голосно впасти: значення з власної бази, з внутрішньої черги.
  • tryFrom - на межі з зовнішнім світом, де невідоме значення - нормальна ситуація, яку треба обробити: введення користувача, вебхуки, сторонні API.

На межі застосунку - валідація, а не винятки:

$request->validate([
    'status' => ['required', Rule::enum(Status::class)],
]);

$status = $request->enum('status', Status::class);

Rule::enum можна ще обмежити: ->only([Status::Draft, Status::Published]) чи ->except(...).

Підводні камені:

  • Тип значення: tryFrom('1') для int-backed enum під strict_types - TypeError, а не null. Значення з запиту спершу приводять до потрібного типу.
  • Видалений варіант при наявних даних у базі: після деплою from() при читанні моделі кидатиме ValueError на старих рядках. Спершу мігрують дані, потім прибирають варіант.
  • Зовнішні API додають нові значення без попередження. Код, що робить from() на їхній відповіді, падає в продакшені наступного ранку. tryFrom плюс логування невідомого значення - надійніше.

Докладніше в документації: BackedEnum::tryFrom

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання