В этой статье мы расскажем, как можно проверить входящие данные через Контроллеры, Запросы формы (FormRequest) и Правила.
Контроллеры
По умолчанию все контроллеры, расширяющие базовый контроллер, наследуют трейт ValidatesRequests
. Он даёт возможность использовать метод validate
в ваших контроллерах.
Например, предположим, что пользователь (User) создаёт статью (Article). Возможно, он вводит Название (name) и какой-то Текст (body) для этой статьи, и у статьи есть дата публикации (publish_at). Тогда валидация в контроллере может выглядеть так:
public function store(Request $request) { $this->validate($request, [ 'name' => 'required|string', 'body' => 'required|string', 'publish_at' => 'required|date_format:Y-m-d H:i:s' ]); // Данные валидны и будет запущен следующий код ... } public function store(Request $request) { // Примечание: также доступен синтаксис массива $request->validate([ 'name' => ['required', 'string'], 'body' => ['required', 'string'], 'publish_at' => ['required', 'date_format:Y-m-d H:i:s'], ]); // Данные валидны и будет запущен следующий код ... } public function store() { request()->validate([ // Правила валидации... ]); // Данные валидны и будет запущен следующий код ... } public function store() { $this->validate(request(), [ // Правила валидации... ]); // Данные валидны и будет запущен следующий код ... }
Следует также отметить, что в ответе метод validate
будут проверенные данные:
public function store(Request $request) { $validatedData = $request->validate([ 'name' => ['required', 'string'], 'body' => ['required', 'string'], 'publish_at' => ['required', 'date_format:Y-m-d H:i:s'], ]); // Я знаю, что ключами в проверенных данных будет только те, что были проверенны успешно, например: name, body, published_at $this->articleService->store($validatedData); }
Или вы можете сделать так:
public function store(Request $request) { $request->validate([ 'name' => ['required', 'string'], 'body' => ['required', 'string'], 'publish_at' => ['required', 'date_format:Y-m-d H:i:s'], ]); // Я знаю, что ключами в проверенных данных будет только те, что были проверенны успешно, например: name, body, published_at $this->articleService->store($request->only('name', 'body', 'published_at')); }
Список доступных правил валидации можно найти здесь.
Запросы форм
Если вы хотите извлечь всю валидационную логику из контроллеров, или же одновременно выполнять и авторизацию и валидацию, то Laravel предоставляет вам класс Запроса формы (Form Request).
Вы можете создать класс Запроса формы, используя один из множества встроенных генераторов:
php artisan make:request StoreArticleRequest
Эта команда создаст следующий класс в app/Http/Requests
:
class StoreArticleRequest extends FormRequest { public function authorize() { return true; } public function rules() { return [ // ]; } }
Класс идёт с двумя методами: authorize
and rules
.
Authorize
Этот метод позволяет предотвратить запуск кода, если возвращает false
. Laravel выбросит ошибку 401.
Пример использования:
public function authorize() { return $this->user()->can('create articles'); }
Rules
Этот метод возвращает массив с правилами, которые мы использовали ранее в контроллере
public function rules() { return [ 'name' => ['required', 'string'], 'body' => ['required', 'string'], 'publish_at' => ['required', 'date_format:Y-m-d H:i:s'], ]; }
Примечание: Вы можете тапйхинтить в этот метод любые необходимые вам зависимости.
Итак, как же использовать этот класс? Тайпхинтим его прямо в метод контроллера:
public function store(StoreArticleRequest $request) { // Валидация успешно пройдена }
Если валидация не пройдет, то пользователя редиректнет обратно с ошибками, записанными в сессию. Если это был AJAX-запрос, то выдаст ошибку 422 Unprocessable Entity
.
Вы можете получить проверенные данные, также как и раньше:
public function store(StoreArticleRequest $request) { $validatedData = $request->validated(); // Добавление в базу данных ... }
Классы кастомных Правил
Если вам не хватает встроенных правил валидации, то вы можете создать своё собственное. Используем одну из команд make:
php artisan make:rule IsValidStateInUSA
Он создаст следующий класс в app/Rules
:
class IsValidStateInUSA implements Rule { public function passes($attribute, $value) { // } public function message() { return 'Сообщение об ошибке валидации.'; } }
В методе pass
находится логика, позволяющая использовать эту проверку. Метод message
содержит сообщение, показываемое в случае неудачной проверки.
В нашей проверке IsValidStateInUSA
(Это код существующего штата США?), нам нужно, чтобы передаваемый элемент был одним из 50 имеющихся кодов:
class IsValidStateInUSA implements Rule { public function passes($attribute, $value) { return in_array(strtoupper($value), [ 'AL', 'AK', 'AZ', ... ]); } public function message() { return 'Несуществующий код штата США.'; } }
Чтобы использовать это правило в контроллере или запросе формы — просто добавляете его вот так:
public function store(Request $request) { $request->validate([ 'state' => ['required', new IsValidStateInUSA], ]); ... }
Обработка ошибок валидации
Если проверка не пройдена, Laravel автоматически редиректит пользователя обратно, с переменной $errors
в сессии.
Создайте файл messages.blade.php
и подключите его в свой основной макета:
@if($errors->any()) <div class="alert alert-danger" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"> <span aria-hidden="true">×</span> </button> @foreach($errors->all() as $error) {{ $error }}<br/> @endforeach </div> @endif
Он покажет все ошибки из сессии или, если вы предпочитаете обрабатывать их по одной, то можете использовать blade-хелпер @error
:
@error('title') <div class="alert alert-danger">{{ $message }}</div> @enderror
Переменная $message
будет передана внутрь тега @error
.
Настройка сообщений об ошибках
Вы можете настроить эти сообщения с помощью третьего параметра метода validate
:
public function store(Request $request) { $this->validate($request, [ 'name' => 'required|string', 'body' => 'required|string', 'publish_at' => 'required|date_format:Y-m-d H:i:s' ], [ 'name.required' => 'Поле Название статьи обязательно для заполнения', 'body.required' => 'Поле Текст статьи обязательно для заполнения', 'publish_at.date_format' => 'Поле Дата публикации имеет неверный формат' ]); // Данные валидны и будет запущен следующий код ... }
При работе с Запросом формы можно настроить сообщения об ошибках в методе messages
:
public function messages() { return [ 'name.required' => 'Поле Название статьи обязательно для заполнения', 'body.required' => 'Поле Текст статьи обязательно для заполнения', 'publish_at.date_format' => 'Поле Дата публикации имеет неверный формат' ]; }
Самая свежая и подробная документация по валидации в Laravel находится здесь.
Автор: Anthony Rappa
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.