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

Як Form Request проходить авторизацію й валідацію і як змінити його поведінку: after, stopOnFirstFailure, редирект і невідомі поля?

Form Request перевіряється ще до виклику методу контролера - коли контейнер створює його як аргумент. Порядок кроків:

  1. authorize() - false чи заборонена відповідь політики → AuthorizationException → 403. Якщо методу немає, запит вважається дозволеним;
  2. prepareForValidation() - підготувати дані (нормалізувати, об'єднати);
  3. rules() + валідатор, разом з after() - додаткові перевірки після основних правил;
  4. при помилці - failedValidation(): редирект назад з помилками чи 422 для JSON;
  5. при успіху - passedValidation(), і лише потім виконується контролер.

after() - перевірки, яким потрібні вже провалідовані значення чи кілька полів одразу:

public function after(): array
{
    return [
        function (Validator $validator) {
            if ($this->date('ends_at') <= $this->date('starts_at')) {
                $validator->errors()->add('ends_at', 'Кінець має бути пізніше за початок.');
            }
        },
        new EnsureSlotIsFree,   // клас з __invoke(Validator $validator)
    ];
}

Налаштування поведінки - властивостями чи, у Laravel 13, атрибутами класу:

#[StopOnFirstFailure]                   // зупинитися на першому полі з помилкою
#[RedirectToRoute('checkout.show')]     // куди повертати замість back()
#[ErrorBag('checkout')]                 // окремий мішок помилок для кількох форм на сторінці
#[FailOnUnknownFields]                  // помилка на полях, яких немає в rules()
final class CheckoutRequest extends FormRequest { /* ... */ }

FailOnUnknownFields - новинка Laravel 13: якщо клієнт надіслав поле, якого немає в rules(), кожне таке поле отримує помилку prohibited. Захищає від масового присвоєння й опечаток у назвах полів на фронтенді. Глобально - FormRequest::failOnUnknownFields() у сервіс-провайдері.

Власна реакція на помилку - перевизначити failedValidation():

protected function failedValidation(Validator $validator): void
{
    throw new HttpResponseException(response()->json([
        'title' => 'Validation failed',
        'errors' => $validator->errors(),
    ], 422));
}

Для API це зазвичай краще зробити один раз у bootstrap/app.php для всіх запитів, а не в кожному класі.

Що пам'ятати:

  • authorize() не замінює політик: вона виконується до валідації, тож дані запиту ще не перевірені - звертатися до них обережно;
  • validated() і safe() повертають лише перевірені поля - саме їх передають у модель, а не all();
  • after() виконується навіть після помилок основних правил - перевірки в ньому мають враховувати, що поля можуть бути порожніми чи некоректними.

Докладніше в документації: Валідація: додаткова перевірка у Form Request

6

Перевір себе

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

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