Валидация данных и вывод ошибок
Валидация проверяет данные пользователя по заданным правилам и автоматически возвращает его к форме с понятными ошибками, если что-то не так.
Суть: метод
$request->validate([...])принимает массив правил вродеrequired|email|min:8. При нарушении Laravel сам редиректит назад с ошибками и старым вводом.
Никогда не доверяйте данным из формы: пользователь может оставить поля пустыми, ввести буквы вместо цены или прислать некорректный email. Валидация — это барьер, который проверяет ввод до того, как он попадёт в базу. Laravel делает её декларативной: вы описываете правила, а фреймворк сам проверяет данные, формирует сообщения об ошибках и возвращает пользователя к форме.
Самый простой способ — метод validate() прямо в контроллере. Вы передаёте массив, где ключ — имя поля, а значение — список правил через вертикальную черту. Если все правила пройдены, выполнение продолжается; если нет — Laravel автоматически прерывает обработку и редиректит назад.
Валидация в контроллере
<?php
public function store(Request $request)
{
// если правила нарушены -> авто-редирект назад с ошибками
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'price' => 'required|numeric|min:0',
'age' => 'nullable|integer|between:18,99',
]);
// сюда дойдём только с корректными данными
Product::create($validated);
return redirect('/products')->with('success', 'Сохранено!');
}Вывод ошибок в шаблоне
При ошибке Laravel кладёт сообщения в переменную $errors, а старый ввод — в хелпер old(), чтобы пользователь не заполнял форму заново:
<form method="POST" action="/products">
@csrf
<input type="text" name="name" value="{{ old('name') }}">
@error('name')
<p style="color:red">{{ $message }}</p>
@enderror
<button>Сохранить</button>
</form>
{{-- общий список ошибок --}}
@if ($errors->any())
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endifКак работает под капотом
Метод validate() прогоняет каждое поле через свои правила. Если хоть одно нарушено, он бросает исключение ValidationException, которое Laravel перехватывает: он делает редирект на предыдущую страницу, кладёт ошибки в сессию (откуда их берёт $errors) и сохраняет старый ввод (его читает old()). Контроллер при этом дальше не выполняется.
ПОТОК ВАЛИДАЦИИ
--------------
POST /products -> validate(rules)
|
+-------------+-------------+
| |
всё ок есть ошибки
| |
продолжаем код throw ValidationException
(Product::create) |
redirect назад
+ $errors + old()
Смоделируем простой валидатор на Python: правила задаются словарём, ошибки собираются в список.
Попробуй сам ▶
# Мини-валидатор: словарь правил -> список ошибок
def validate(data, rules):
errors = {}
for field, checks in rules.items():
value = data.get(field)
for check in checks:
if check == 'required' and not value:
errors[field] = 'Поле обязательно'
elif check == 'email' and value and '@' not in value:
errors[field] = 'Некорректный email'
return errors
rules = {'name': ['required'], 'email': ['required', 'email']}
print(validate({'name': 'Анна', 'email': 'bad'}, rules))
print(validate({'name': 'Анна', 'email': '[email protected]'}, rules))
Частые ошибки
- Доверять
validate()без вывода ошибок. Без блока@errorпользователь не поймёт, что пошло не так. - Терять старый ввод. Без
old()форма очищается, и пользователь злится. - Дублировать правила. Если одни и те же правила в нескольких местах — пора выносить их в Form Request.
Best practices
- Используйте результат
validate()(он возвращает только проверенные поля) дляcreate(). - Для сложных форм выносите правила в отдельный класс Form Request (следующий урок).
- Всегда подставляйте
old()в поля и показывайте@errorрядом с ними.
Итог: валидация декларативно проверяет ввод и автоматически возвращает пользователя к форме с ошибками и старыми данными. Дальше вынесем правила в отдельные классы Form Request для чистоты контроллеров.