Формы и валидация в Laravel: что знать до первой формы
Первая форма на Laravel падает не там, где ждёшь: то CSRF-токен, то старые данные не возвращаются в поле, то ошибки не выводятся. Разбираем базовый набор, который нужен до старта.

К концу этой статьи у вас будет рабочая форма на Laravel 11.x: поля, проверка данных на сервере, вывод ошибок и возврат введённых значений при неудаче. На всё уходит около 30–40 минут, если проект уже развёрнут. Мы намеренно не углубляемся в устройство контейнера или жизненный цикл запроса — только то, что нужно, чтобы форма заработала правильно с первого раза.
Валидация в Laravel устроена так, что новичок легко пропускает три вещи: защиту от CSRF, возврат старого ввода и корректный вывод ошибок под полями. Каждая из них тихо ломает форму, не выдавая явной ошибки. Поэтому идём по шагам.
Что нужно иметь до начала
Проверьте окружение прежде, чем писать первую строку. Если чего-то не хватает, форма может отправляться, но не сохраняться, а понять причину без этих деталей тяжело.
- Laravel 11.x — команды и структура ниже проверены на этой версии. В 10.x почти всё совпадает, отличия отмечу отдельно.
- PHP 8.2+ — минимум для Laravel 11.
- Развёрнутый проект: команда
php artisan serveуже поднимает сайт наhttp://127.0.0.1:8000. - Настроенная база в
.envи выполненные миграции, если форма будет что-то сохранять. - Шаблонизатор Blade — он идёт из коробки, отдельно ставить не нужно.
Если php artisan serve отдаёт ошибку про APP_KEY, выполните php artisan key:generate. Без ключа приложения сессии и, как следствие, вывод ошибок валидации работать не будут.
Три подхода к валидации — и какой брать сначала
Laravel даёт несколько способов проверить данные. Для первой формы важно не распыляться.
| Подход | Где живёт код | Когда брать |
|---|---|---|
$request->validate() | прямо в методе контроллера | простая форма, 3–6 полей — начните с этого |
| Form Request | отдельный класс-запрос | сложные правила, повтор в нескольких местах |
Фасад Validator::make() | ручное создание валидатора | нестандартный сценарий, проверка вне HTTP-запроса |
Для старта берём $request->validate(). Он сам перенаправит пользователя назад при ошибке и положит ошибки в сессию — половину работы делает за вас.
Шаг 1. Маршруты
Нужно два маршрута: один показывает форму, второй принимает данные. Откройте routes/web.php:
use App\Http\Controllers\FeedbackController;
// Показать форму
Route::get('/feedback', [FeedbackController::class, 'create']);
// Принять данные формы
Route::post('/feedback', [FeedbackController::class, 'store']);Проверка: команда php artisan route:list должна показать обе строки — GET и POST на /feedback.
Шаг 2. Контроллер
Создайте контроллер командой:
php artisan make:controller FeedbackControllerВ файле app/Http/Controllers/FeedbackController.php опишите два метода:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class FeedbackController extends Controller
{
// Отдаёт страницу с формой
public function create()
{
return view('feedback');
}
// Принимает и проверяет данные
public function store(Request $request)
{
// Правила проверки для каждого поля
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email',
'message' => 'required|string|min:10',
]);
// Сюда попадаем только если проверка прошла.
// $validated содержит только проверенные поля.
return back()->with('success', 'Сообщение отправлено');
}
}Ключевой момент: если проверка не прошла, validate() сам прервёт выполнение и вернёт пользователя назад с ошибками. Строки после него в этом случае не выполнятся — не нужно писать if.
Шаг 3. Шаблон формы
Создайте файл resources/views/feedback.blade.php. Здесь три вещи, которые новичок пропускает: директива @csrf, вывод ошибок и old() для возврата ввода.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Обратная связь</title>
</head>
<body>
@if (session('success'))
<p>{{ session('success') }}</p>
@endif
<form method="POST" action="/feedback">
@csrf
<p>
<label>Имя</label>
<input type="text" name="name" value="{{ old('name') }}">
@error('name') <span>{{ $message }}</span> @enderror
</p>
<p>
<label>Email</label>
<input type="email" name="email" value="{{ old('email') }}">
@error('email') <span>{{ $message }}</span> @enderror
</p>
<p>
<label>Сообщение</label>
<textarea name="message">{{ old('message') }}</textarea>
@error('message') <span>{{ $message }}</span> @enderror
</p>
<button type="submit">Отправить</button>
</form>
</body>
</html>Проверка: откройте http://127.0.0.1:8000/feedback — форма должна отобразиться. Отправьте её пустой: под каждым обязательным полем появится текст ошибки, а введённые значения останутся в полях.
Директива @csrf — не формальность. Без неё Laravel отклонит POST-запрос с ошибкой 419, и форма просто не отправится. Это первая причина, по которой «форма не работает» у новичков.Что делает каждая деталь шаблона
@csrf— вставляет скрытое поле с токеном*. Обязательно для любого POST/PUT/PATCH/DELETE.old('name')— возвращает то, что пользователь ввёл до неудачной отправки. Без неё форма очищается при ошибке, и человек вводит всё заново.@error('name') ... @enderror— показывает сообщение об ошибке для конкретного поля, если оно есть.
Если не получилось
Пять ошибок, которые встречаются чаще всего.
- 419 Page Expired при отправке. Забыли
@csrfвнутри<form>, либо у приложения нетAPP_KEY. Проверьте оба. - Ошибки валидации не выводятся. Обычно причина в сессии: маршрут не в группе
webили отключён middleware сессий. В стандартномroutes/web.phpвсё работает из коробки — проверьте, что маршрут именно там, а не вroutes/api.php. - Поля очищаются после ошибки. Не использован
old()в атрибутеvalue. У<textarea>значение ставится между тегами, а не в атрибут — частая путаница. - MethodNotAllowedHttpException. В форме
method="POST", но маршрут описан какRoute::get. Сверьте методы. - Данные приходят пустыми в контроллер. У полей
<input>не задан атрибутnameили он не совпадает с ключом в правилахvalidate().
Что настроить дальше
Форма работает — дальше есть куда расти, но по одному шагу за раз.
- Когда правил станет много или они повторятся в нескольких местах — вынесите их в Form Request командой
php artisan make:request. Логика та же, но код чище. - Русские тексты ошибок настраиваются в языковых файлах — это отдельная тема, здесь мы оставили сообщения по умолчанию.
- Сохранение в базу через модель Eloquent — следующий логичный шаг после проверки данных.
Полный список доступных правил (required, email, unique, confirmed и десятки других) смотрите в разделе Validation официальной документации той версии Laravel, которую вы поставили — набор правил между версиями иногда пополняется.
Инфобез и 152-ФЗ: Аудит политик конфиденциальности, правила сбора cookie.
Спросить за 20 ₽Источники: Laravel Documentation — Validation, Laravel Documentation — CSRF Protection
Частые вопросы
У меня Laravel 10, а не 11 — код подойдёт?
Форма отправляется, но выдаёт ошибку 419 — что делать?
Можно проверять данные только на клиенте, через атрибуты HTML?
Почему ошибки валидации не выводятся, хотя правила заданы?
В чём разница между validate() и Form Request, если результат одинаковый?
Как вернуть сообщения об ошибках на русском?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.