← Назад к вопросам

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

2.0 Middle🔥 252 комментариев
#Фреймворки

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

🛡️ Как работает валидация в Laravel

Валидация в Laravel — это мощный и гибкий механизм проверки входящих данных, который следует философии «соглашения конфигурации» (convention over configuration). Ядро системы построено вокруг класса Illuminate\Validation\Validator, но разработчики чаще работают с высокоуровневыми абстракциями.

🔍 Основные подходы к валидации

Laravel предлагает несколько способов валидации, каждый из которых подходит для разных сценариев:

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

Метод validate() доступен в контроллерах через трейт ValidatesRequests:

use Illuminate\Http\Request;

public function store(Request $request)
{
    $validated = $request->validate([
        'title' => 'required|string|max:255',
        'email' => 'required|email|unique:users,email',
        'age' => 'nullable|integer|min:18',
        'password' => 'required|confirmed|min:8',
        'avatar' => 'image|mimes:jpeg,png|max:2048',
    ]);
    
    // Данные уже валидны
    Post::create($validated);
}

2. Создание Form Request объектов

Для сложной валидации с собственной логикой создаются отдельные классы:

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

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    public function authorize()
    {
        // Проверка прав пользователя
        return $this->user()->can('create', Post::class);
    }
    
    public function rules()
    {
        return [
            'title' => ['required', 'string', 'max:255'],
            'content' => ['required', 'string', 'min:100'],
            'published_at' => ['nullable', 'date', 'after_or_equal:today'],
        ];
    }
    
    public function messages()
    {
        return [
            'title.required' => 'Пожалуйста, укажите заголовок статьи',
            'content.min' => 'Содержание должно быть не менее 100 символов',
        ];
    }
    
    public function withValidator($validator)
    {
        $validator->after(function ($validator) {
            if ($this->somethingElseIsInvalid()) {
                $validator->errors()->add('field', 'Дополнительная проверка не пройдена');
            }
        });
    }
}

📋 Типы правил валидации

Laravel предоставляет десятки встроенных правил, которые можно разделить на категории:

Базовые правила:

  • required, nullable, sometimes
  • string, integer, boolean, array, date
  • email, url, ip, uuid

Правила для сравнения:

  • min:value, max:value, between:min,max
  • gt:field, lt:field, gte:field, lte:field
  • same:field, different:field

Правила для баз данных:

  • exists:table,column
  • unique:table,column,except,idColumn

Правила для файлов:

  • file, image, mimes:jpeg,png,pdf, max:size_in_kb
  • dimensions:min_width=100,min_height=200

🎯 Кастомные правила и расширения

Для нестандартных проверок можно создавать собственные правила:

php artisan make:rule Uppercase
namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Uppercase implements Rule
{
    public function passes($attribute, $value)
    {
        return strtoupper($value) === $value;
    }
    
    public function message()
    {
        return 'Поле :attribute должно быть в верхнем регистре';
    }
}

// Использование:
public function rules()
{
    return [
        'code' => ['required', new Uppercase],
    ];
}

🔄 Валидация вручную

Иногда нужно выполнить валидацию вне контроллера:

use Illuminate\Support\Facades\Validator;

$validator = Validator::make($request->all(), [
    'email' => 'required|email',
], [
    'email.required' => 'Email обязателен для заполнения',
]);

if ($validator->fails()) {
    return redirect()->back()
        ->withErrors($validator)
        ->withInput();
}

// Или быстрая проверка
$validator->validate(); // Выбросит ValidationException

🌐 AJAX-валидация и JSON-ответы

При отправке AJAX-запросов Laravel автоматически возвращает ошибки в JSON-формате:

// В JavaScript можно обработать так:
axios.post('/api/posts', data)
    .then(response => {
        // Успех
    })
    .catch(error => {
        if (error.response.status === 422) {
            const errors = error.response.data.errors;
            // Обработка ошибок валидации
        }
    });

⚡ Оптимизация и продвинутые техники

Условная валидация:

$rules = [
    'email' => 'required|email',
    'password' => 'required|min:8',
];

$validator = Validator::make($data, $rules);
$validator->sometimes('credit_card', 'required', function ($input) {
    return $input->payment_type === 'credit_card';
});

Валидация массивов:

$rules = [
    'users.*.email' => 'required|email',
    'users.*.age' => 'required|integer|min:18',
];

Подготовка данных перед валидацией:

$validator = Validator::make($data, $rules);
$validator->prepareForValidation();

// Или в FormRequest:
protected function prepareForValidation()
{
    $this->merge([
        'slug' => Str::slug($this->title),
    ]);
}

📊 Обработка ошибок

После валидации ошибки доступны через объект Validator или ValidationException:

// Получить все ошибки
$errors = $validator->errors()->all();

// Получить ошибки для конкретного поля
$fieldErrors = $validator->errors()->get('email');

// Проверить наличие ошибки для поля
if ($validator->errors()->has('email')) {
    // Действие
}

В шаблонах Blade ошибки выводятся автоматически:

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<!-- Для конкретного поля -->
<input type="text" name="email" value="{{ old('email') }}">
@error('email')
    <div class="text-danger">{{ $message }}</div>
@enderror

🏗️ Архитектурные аспекты

  1. Инверсия зависимостей — валидатор внедряется через контейнер служб
  2. Событийная модель — можно подписываться на события валидации
  3. Локализация — все сообщения об ошибках легко переводятся
  4. Расширяемость — можно добавлять свои правила, ресолверы данных, форматтеры ошибок

💡 Лучшие практики

  • Используйте Form Request для сложной бизнес-логики валидации
  • Выносите регулярные выражения в конфигурации или константы
  • Для часто используемых правил создавайте макросы валидатора
  • Не забывайте про авторизацию в методе authorize() Form Request
  • Тестируйте валидацию с помощью PHPUnit или Pest

Система валидации Laravel сочетает в себе простоту для базовых случаев и мощную расширяемость для сложных сценариев, следуя принципу "батарейки в комплекте" (batteries included), что делает её одной из самых удобных среди PHP-фреймворков.

Как работает валидация в Laravel? | PrepBro