Формы и валидация в Laravel: пошаговая инструкция
К концу вы соберёте рабочую форму регистрации с проверкой полей на сервере, выводом ошибок в шаблоне и сохранением введённых данных. Заложите на всё около 40 минут.

К концу этой инструкции у вас будет форма регистрации на Laravel: контроллер принимает данные, проверяет их правила валидации, а при ошибке возвращает пользователя на форму с подсвеченными полями и уже введённым текстом. Всё делается штатными средствами фреймворка, без сторонних пакетов. Времени — минут 40, если Laravel уже установлен.
Примеры проверены на Laravel 11.x и PHP 8.2. В версиях 10 и 11 API валидации, которое здесь используется, работает одинаково, так что если у вас 10.x — код тоже подойдёт.
Что нужно иметь до начала
Прежде чем писать код, убедитесь, что у вас есть:
- установленный Laravel 11.x — проверьте командой
php artisan --version; - PHP 8.2 или новее (Laravel 11 требует минимум 8.2);
- настроенная база данных в файле
.env— подойдёт SQLite, MySQL или PostgreSQL; - запущенный локальный сервер:
php artisan serveотдаёт приложение наhttp://127.0.0.1:8000; - выполненная миграция таблицы пользователей — в свежем проекте она уже есть, запустите
php artisan migrate.
Если php artisan migrate ругается на подключение к базе — сначала разберитесь с .env, дальше идти нет смысла: сохранять данные будет некуда.
Шаг 1. Роуты для формы
Откройте routes/web.php и добавьте два маршрута: один показывает форму (GET), второй принимает отправку (POST).
use App\Http\Controllers\RegisterController;
Route::get('/register', [RegisterController::class, 'show'])->name('register.show');
Route::post('/register', [RegisterController::class, 'store'])->name('register.store');Проверка: выполните php artisan route:list. В списке должны появиться две строки с путём register — GET и POST.
Шаг 2. Контроллер
Создайте контроллер командой:
php artisan make:controller RegisterControllerКоманда создаст файл app/Http/Controllers/RegisterController.php. Откройте его и добавьте два метода — показ формы и обработку.
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class RegisterController extends Controller
{
// Показываем пустую форму
public function show()
{
return view('register');
}
// Принимаем и проверяем данные
public function store(Request $request)
{
$validated = $request->validate([
'name' => ['required', 'string', 'min:2', 'max:255'],
'email' => ['required', 'email', 'unique:users,email'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
// До сюда код дойдёт, только если все правила прошли
User::create([
'name' => $validated['name'],
'email' => $validated['email'],
'password' => Hash::make($validated['password']),
]);
return redirect('/register')->with('success', 'Регистрация прошла успешно');
}
}Ключевое здесь — метод $request->validate(). Если хотя бы одно правило не прошло, Laravel сам прерывает выполнение, кладёт ошибки в сессию и делает редирект обратно на форму. Строки после validate() при провале не выполнятся — писать if не нужно.
Проверка: пока форма не готова, но php artisan route:list уже не должен показывать ошибку про отсутствующий класс контроллера.
Что делают правила
required— поле обязательно и не может быть пустым;email— значение должно быть похоже на адрес почты;unique:users,email— такого email ещё нет в таблицеusers, колонкаemail;confirmed— должно быть второе полеpassword_confirmationс тем же значением;min:8— минимум 8 символов.
Полный список доступных правил смотрите в документации Laravel — их несколько десятков, и они меняются между мажорными версиями.
Шаг 3. Шаблон формы
Создайте файл resources/views/register.blade.php. Здесь важны три вещи: директива @csrf, вывод ошибок через @error и возврат введённого значения через 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="{{ route('register.store') }}">
@csrf
<div>
<label>Имя</label>
<input type="text" name="name" value="{{ old('name') }}">
@error('name')
<span style="color:red">{{ $message }}</span>
@enderror
</div>
<div>
<label>Email</label>
<input type="email" name="email" value="{{ old('email') }}">
@error('email')
<span style="color:red">{{ $message }}</span>
@enderror
</div>
<div>
<label>Пароль</label>
<input type="password" name="password">
@error('password')
<span style="color:red">{{ $message }}</span>
@enderror
</div>
<div>
<label>Повтор пароля</label>
<input type="password" name="password_confirmation">
</div>
<button type="submit">Зарегистрироваться</button>
</form>
</body>
</html>Директива @csrf вставляет скрытое поле с токеном*. Без него Laravel отклонит POST-запрос с ошибкой 419. Функция old('name') подставляет то, что пользователь ввёл в прошлый раз — иначе при ошибке валидации форма очистится полностью, и человек будет заполнять всё заново.
Проверка: откройте http://127.0.0.1:8000/register — должна отобразиться форма с четырьмя полями и кнопкой.
Главная ошибка новичка в Laravel — не связать value="{{ old('name') }}" с полем. Валидация работает, ошибки выводятся, но при каждом промахе пользователь теряет всё, что напечатал. На форме из десяти полей это гарантированный отказ от регистрации.* CSRF-токен — уникальная строка, привязанная к сессии. Она подтверждает, что форму отправили с вашего сайта, а не с поддельной страницы злоумышленника.
Шаг 4. Проверяем поведение
Отправьте форму пустой. Вы должны вернуться на /register, под каждым обязательным полем появится текст ошибки на русском или английском (зависит от локали приложения). Теперь заполните имя и email, но пароли сделайте разными — увидите сообщение о том, что подтверждение не совпадает. Заполните корректно — появится строка «Регистрация прошла успешно», а в таблице users прибавится запись.
Локализация сообщений
По умолчанию Laravel отдаёт ошибки на английском. Чтобы получить русский текст, опубликуйте языковые файлы и добавьте русскую локаль. Точный набор команд для публикации переводов смотрите в разделе Localization документации — механизм менялся: в старых версиях файлы лежали в каталоге resources/lang, в новых — в lang в корне проекта.
Шаг 5. Выносим правила в Form Request
Когда правил становится много, держать их в контроллере неудобно. Laravel предлагает отдельный класс — Form Request. Создайте его:
php artisan make:request RegisterRequestФайл появится в app/Http/Requests/RegisterRequest.php. Перенесите правила туда:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RegisterRequest extends FormRequest
{
// Разрешаем запрос всем; здесь можно проверять права
public function authorize(): bool
{
return true;
}
// Те же правила, что были в контроллере
public function rules(): array
{
return [
'name' => ['required', 'string', 'min:2', 'max:255'],
'email' => ['required', 'email', 'unique:users,email'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
];
}
}Обратите внимание на метод authorize(): если он вернёт false, Laravel отклонит запрос с ошибкой 403 ещё до проверки правил. По умолчанию make:request ставит false — не забудьте поменять на true, иначе форма будет отдавать «Forbidden» без внятной причины.
Теперь в контроллере замените Request на RegisterRequest:
use App\Http\Requests\RegisterRequest;
public function store(RegisterRequest $request)
{
$validated = $request->validated();
// дальше — тот же User::create()
}Laravel сам применит правила из rules() до входа в метод. Контроллер стал чище, а правила можно переиспользовать.
Если не получилось
- 419 Page Expired при отправке — в форме нет
@csrfили истекла сессия. Проверьте директиву внутри тега<form>. - The name field is required, хотя поле заполнено — не совпадает атрибут
nameу<input>и ключ в правилах. Регистр важен. - 403 Forbidden после перехода на Form Request — метод
authorize()возвращаетfalse. Поставьтеreturn true. - SQLSTATE... no such table: users — не прогнана миграция. Запустите
php artisan migrate. - Ошибки не выводятся под полями — блок
@error(...)ссылается на имя, которого нет в правилах, или вы забыли@enderror.
Что делать дальше
Форма работает, но это только серверная валидация. Следующие шаги, каждый — отдельная тема:
- добавьте кастомные сообщения об ошибках — метод
messages()в Form Request; - для полей, которые нельзя проверить простым правилом, посмотрите правило
Ruleи замыкания в документации по валидации; - если строите API, а не формы, замените редирект на JSON-ответ — Laravel по заголовку
Accept: application/jsonсам вернёт ошибки в формате JSON со статусом 422; - клиентскую проверку в браузере добавляйте поверх серверной, но не вместо неё — данные с фронтенда доверять нельзя.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: Laravel Validation — официальная документация, Laravel Form Request Validation
Частые вопросы
У меня Laravel 10, а не 11. Код подойдёт?
Форма отдаёт ошибку 419 при отправке. Что не так?
Ошибки выводятся на английском, а нужен русский. Как переключить?
Что делать, если правило validate() не покрывает мой случай?
Нужна ли клиентская валидация, если есть серверная?
Почему после ошибки форма очищается и как это исправить?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.