Laravel. Валидация данных. Часть вторая из трех
20.09.2020
Теги: Laravel • Web-разработка • Теория • Форма • Фреймворк • ШаблонСайта
Валидация в отдельном классе
Способ, который мы рассмотрели в первой части, подходит для проверки небольшого количества полей. Для более сложных случаев лучше создать отдельный класс, который будет проверять данные формы.
1. Создание класса валидатора
Создать такой класс можно с помощью artisan-команды:
> cd D:/work/localhost25/www > php artisan make:request PostRequest
В результате будет создан файл app/Http/Requests/PostRequest.php
, который будет проверять данные формы при создании нового поста блога.
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class PostRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return false; } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'title' => 'required|unique:posts|min:3|max:100', 'excerpt' => 'required|min:100|max:200', 'body' => 'required', ]; } }
Далее изменяем метод store()
контроллера PostController
, указывая тип параметра $request
как PostRequest
вместо Request
.
<?php namespace App\Http\Controllers; use App\Post; use Illuminate\Http\Request; use App\Http\Requests\PostRequest; class PostController extends Controller { /* ... */ public function store(PostRequest $request) { $post = new Post(); $post->title = $request->input('title'); $post->excerpt = $request->input('excerpt'); $post->body = $request->input('body'); $post->save(); return redirect() ->route('post.index') ->with('success', 'Новый пост успешно создан'); } /* ... */ }
Входящий запрос перед вызовом метода контроллера store()
будет проверяться на соответствие заданным правилам автоматически, что позволит не загромождать контроллер логикой валидации. Если проверка не пройдена, то при традиционном запросе ошибки записываются в сессию и будут доступны в шаблонах. Если был AJAX-запрос, пользователю будет возвращен HTTP-ответ с кодом 422, включая JSON с ошибками.
2. Доработка класса валидатора
Мы создали проверку данных при добавлении нового поста блога, но нужна еще проверка при редактировании существующего поста. Чтобы не создавать новый класс валидации — можно поступить так, как показано ниже.
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class PostRequest extends FormRequest { /** * Возвращает массив правил для проверки полей формы * * @return array */ public function rules() { switch ($this->method()) { case 'POST': { return [ 'title' => 'required|unique:posts|min:3|max:100', 'excerpt' => 'required|min:100|max:200', 'body' => 'required', ]; } case 'PATCH': { return [ 'id' => 'required|exists:posts,id', 'title' => 'required|min:3|max:100', 'excerpt' => 'required|min:100|max:200', 'body' => 'required' ]; } } } /* ... */ }
3. Проверка прав в валидаторе
Класс FormRequest
содержит в себе метод authorize()
. В этом методе можно проверить, имеет ли аутентифицированный пользователь права на выполнение данного запроса. Например, можно проверить, есть ли у пользователя право для добавления комментариев в блог:
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class PostRequest extends FormRequest { /** * Определить, есть ли права у этого пользователя на этот запрос * * @return bool */ public function authorize() { $comment = Comment::find($this->route('comment')); return $comment && $this->user()->can('update', $comment); } /* ... */ }
Так как FormRequest
расширяет базовый класс Request
, мы можем использовать метод user()
, чтобы получить доступ к текущему пользователю.Так же обратите внимание на вызов метода route()
— он предоставляет доступ к параметрам URI, определенным в роуте (в приведенном ниже примере это {comment}
):
Route::post('comment/{comment}');
Если метод authorize()
возвращает false
, автоматически генерируется ответ с кодом 403 и метод контроллера не выполняется. Если логика авторизации организована в другом месте приложения, нужно просто вернуть true
из метода authorize()
:
public function authorize() { return true; }
4. Текст сообщений об ошибках
Метод messages()
позволяет кастомизировать сообщения об ошибках. И должен возвращать массив атрибутов/правил и соответствующих им сообщений об ошибках:
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class PostRequest extends FormRequest { /** * Возвращает массив правил для проверки полей формы * * @return array */ public function rules() { return [ 'title' => 'required|unique:posts|min:3|max:100', 'excerpt' => 'required|min:100|max:200', 'body' => 'required', ]; } /** * Возвращает массив сообщений об ошибках для заданных правил * * @return array */ public function messages() { return [ 'title.required' => 'Поле «Заголовок» обязательно для заполнения', 'title.unique' => 'Такой заголовок уже существует, придумайте другой', 'title.min' => 'Поле «Заголовок» должно быть не меньше :min символов', 'title.max' => 'Поле «Заголовок» должно быть не больше :max символов', 'excerpt.required' => 'Поле «Анонс поста» обязательно для заполнения', 'excerpt.min' => 'Поле «Анонс поста» должно быть не меньше :min символов', 'excerpt.max' => 'Поле «Анонс поста» должно быть не больше :max символов', 'body.required' => 'Поле «Текст поста» обязательно для заполнения', ]; } /* ... */ }
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class PostRequest extends FormRequest { /** * Возвращает массив правил для проверки полей формы * * @return array */ public function rules() { return [ 'title' => 'required|unique:posts|min:3|max:100', 'excerpt' => 'required|min:100|max:200', 'body' => 'required', ]; } /** * Возвращает массив сообщений об ошибках для заданных правил * * @return array */ public function messages() { return [ 'required' => 'Поле «:attribute» обязательно для заполнения', 'unique' => 'Такое значение поля «:attribute» уже используется', 'min' => 'Поле «:attribute» должно быть не меньше :min символов', 'max' => 'Поле «:attribute» должно быть не больше :max символов', ]; } /** * Возвращает массив дружественных пользователю названий полей * * @return array */ public function attributes() { return [ 'title' => 'Заголовок', 'excerpt' => 'Анонс поста', 'body' => 'Текст поста' ]; } }
5. Отображение ошибок
В случае ошибок пользователь будет перенаправлен на предыдущую страницу, а все ошибки валидации будут автоматически записаны во flash-переменные.
<!-- resources/views/post/create.blade.php --> <h1>Создать пост</h1> @if ($errors->any()) <div class="alert alert-danger"> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif
Дополнительно
- Laravel. Валидация данных. Часть третья из трех
- Laravel. Валидация данных. Часть первая из трех
- Блог на Laravel 7, часть 9. Панель управления — создание, публикация, удаление комментариев
- Блог на Laravel 7, часть 8. Панель управления — CRUD для категорий, тегов и пользователей
- Блог на Laravel 7, часть 7. Панель управления — создание, публикация, удаление постов
- Блог на Laravel 7, часть 2. Регистрация и аутентификация, восстановление пароля
- Laravel. Отправка почты по событию
Поиск: Laravel • Web-разработка • Теория • Форма • Фреймворк • Шаблон сайта • Валидация