Значення з запиту, бази, черги чи стороннього 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плюс логування невідомого значення - надійніше.