Урок 10

Валидация в контроллерах

Валидация проверяет входящие данные до их использования. В Laravel она встроена в контроллеры и роуты.

Метод validate

public function store(Request $request)
{
    $validated = $request->validate([
        'title' => 'required|string|max:255',
        'body' => 'required|string|min:10',
        'email' => 'required|email|unique:users',
        'age' => 'nullable|integer|min:18|max:120',
    ]);

    Post::create($validated);
}

Если валидация не проходит:

  • Для web — редирект назад с ошибками в сессии
  • Для API — JSON 422 с ошибками

Основные правила

  • required — поле обязательно
  • nullable — может быть пустым
  • string — строка
  • integer — целое число
  • email — корректный email
  • min:8, max:255 — границы
  • between:18,120 — диапазон
  • in:admin,user — значение из списка
  • unique:users,email — уникально в таблице
  • exists:tags,id — существует в таблице
  • confirmed — совпадает с _confirmation
  • date, before:today, after:today — даты
  • image, mimes:jpg,png, max:2048 — файлы
  • array, tags.* — массивы

Form Request

Если правил много — их выносят в отдельный класс:

php artisan make:request StorePostRequest
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'title' => 'required|string|max:255',
            'body' => 'required|string|min:10',
        ];
    }

    public function messages(): array
    {
        return [
            'title.required' => 'Заголовок обязателен',
        ];
    }

    public function attributes(): array
    {
        return [
            'title' => 'заголовок',
        ];
    }
}

Использование:

public function store(StorePostRequest $request)
{
    Post::create($request->validated());
}

authorize() определяет право на действие. rules() — правила. messages() — сообщения. attributes() — человекочитаемые имена полей.

Подготовка данных

prepareForValidation() позволяет изменить данные до валидации:

protected function prepareForValidation(): void
{
    $this->merge([
        'slug' => Str::slug($this->title),
    ]);
}

Вывод ошибок в Blade

@if ($errors->any())
    <ul>
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif

<input name="title" value="{{ old('title') }}">

@error('title')
    <p>{{ $message }}</p>
@enderror

old() возвращает предыдущее значение после ошибки.