Как работает валидация данных в Laravel?

«Как работает валидация данных в Laravel?» — вопрос из категории Laravel, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Валидация в Laravel — это мощный и выразительный механизм проверки входящих HTTP-запросов. Она централизована, имеет множество встроенных правил и легко расширяется.

Основные подходы:

1. Валидация в контроллере (наиболее частый способ)

Используется метод validate() у объекта IlluminateHttpRequest. При неудаче автоматически генерируется редирект назад с ошибками в сессии.

public function store(Request $request) {
    // Валидация и получение проверенных данных
    $validatedData = $request->validate([
        'title' => 'required|string|max:255|unique:posts,title',
        'body' => 'required|string|min:100',
        'published_at' => 'nullable|date|after:now',
        'category_id' => 'required|exists:categories,id',
        'tags' => 'array',
        'tags.*' => 'integer|distinct|exists:tags,id', // Валидация каждого элемента массива
    ]);

    // $validatedData содержит только проверенные поля
    $post = Post::create($validatedData);
    return redirect()->route('posts.show', $post);
}

2. Form Request Validation (для сложной логики)

Создается отдельный класс, что идеально для повторного использования и сложных правил.

php artisan make:request StorePostRequest
// app/Http/Requests/StorePostRequest.php
class StorePostRequest extends FormRequest {
    public function authorize() {
        // Проверка прав доступа пользователя
        return $this->user()->can('create', Post::class);
    }

    public function rules() {
        return [
            'title' => ['required', 'string', 'max:255', Rule::unique('posts')->ignore($this->route('post'))],
            'body' => 'required|string|min:100',
        ];
    }

    public function messages() {
        return [
            'title.required' => 'Заголовок поста обязателен.',
            'body.min' => 'Текст поста должен быть не менее :min символов.',
        ];
    }

    public function withValidator($validator) {
        $validator->after(function ($validator) {
            if ($this->somethingElseIsInvalid()) {
                $validator->errors()->add('field', 'Дополнительная проверка не пройдена.');
            }
        });
    }
}

// Использование в контроллере
public function store(StorePostRequest $request) {
    // Запрос уже валидирован и авторизован
    $validated = $request->validated();
    // ...
}

3. Ручная валидация

Через фасад Validator, когда нужен больший контроль (например, для API без редиректа).

use IlluminateSupportFacadesValidator;

$validator = Validator::make($request->all(), [
    'email' => 'required|email',
    'amount' => 'required|numeric|min:1',
]);

if ($validator->fails()) {
    // Для API
    return response()->json([
        'errors' => $validator->errors()
    ], 422);
    // Или для веба
    // return redirect()->back()->withErrors($validator)->withInput();
}

$validData = $validator->validated();

Ключевые возможности:

  • Более 90 встроенных правил: required, email, unique, exists, min, max, regex, confirmed (для паролей), mimes (для файлов) и многие другие.
  • Условная валидация: Правило sometimes позволяет применять правила только если поле присутствует.
  • Кастомные правила: Можно создавать свои правила классами или замыканиями с помощью Validator::extend().
  • Автоматическое связывание ошибок с представлением: В шаблонах Blade коллекция $errors доступна глобально.
  • Валидация вложенных массивов: Используется синтаксис с точкой (например, products.*.name).