laravel

Как валидировать входящие пользовательские данные в Laravel

Laravel является наиболее популярным PHP фрэймворком. Обработка и валидация пользовательских данных это возможно первая вещь с которой нужно начать изучение Laravel. В этой статье будет показано три метода валидаций пользовательских данных.

Для этой статьи предполагается что у вас уже есть форма и существует что-то похожее на следующие два маршрута:

Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);

Главный принцип валидации очень простой: вы берете некоторый ввод, вы определяете некоторые правила для теста напротив ввода, и валидатор проверяет есть ли правила применяемые к вводу. Если нет, то передается подходящее сообщение с ошибкой. В зависимости от метода, что вы используете сообщения об ошибке могут возвращаться автоматически или задаваться вручную.

Если ввод валиден, оно будет автоматически продолжено как нормальное. Это позволяет очень легко делать проверку почти перед каждым вводом и предотвращать ошибки и необычные вещи в будущем.

Первый метод может быть сразу применен к запросу: $request->validate($rules). В вашем контроллере у вас есть что-то вроде этого:

use Illuminate\Http\Request;
 
public function store(Request $request): mixed
{
    $validated = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);
 
    // The input is valid...
}

Здесь происходит следующее:

  1. Мы берем ввод из переменной $request
  2. Мы применяем метод validate() как тут ($request->validate())
  3. Результат сохраняется в переменной $validated

Что происходит когда валидация завершилась неудачно?

Если валидация терпит неудачу, то laravel автоматически перенаправляет на предыдущую страницу. Таким образом на страницу где расположена форма. На этой странице, Laravel вставляет переменную $errors. Вы можете использовать эту переменную для отображения ошибок:

<!-- /resources/views/post/create.blade.php -->
 
<h1>Create Post</h1>
 
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
 
<!-- Create Post Form -->

Что происходит если валидация прошла успешно?

Если валидация прошла успешно, будет переход на следующий шаг в контроллере.

Метод валидации 2: Laravel Form Request

Если вы имеете много пользовательских данных, может быть полезно размещать всю логику в одном месте. Если вы видели пример выше, то можно оказаться в ситуаций, где каждый контроллер стал загроможденным правилами валидации. К счастью, Laravel имеет решение для этого: Form Requests.

Form Requests это отдельный класс. Если вы создаете Form Request для каждой формы, код организуется намного лучше, потому что вся логика расположена в одном месте. Также это позволяет повторно применять правила, без повторного их написания, например в двух контроллерах. Когда вы захотите использовать их в своих контроллерах используйте экземпляр Form Request, вместо регулярного Request $request.

Для создания Form Request, нужно запустить следующую artisan команду из вашего каталога проекта:

php artisan make:request StorePostRequest

Request будет расположен в следующем файле app/Http/Requests/StorePostRequest.php. Этот файл включает два метода: rules() и authorize().

Form Request метод rules()

Метод rules() очень простой метод. По сути это обычная функция в которой определяются правила валидации и повторно применяются. Этот метод возвращает только массив правил:

public function rules(): array
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

Form Request: метод authorize()

Метод authorize() является второй функцией в вашем Form Request. Эта функция должна возвращать boolean true/false. Короче говоря вы можете выполнять некоторую сортировку, для проверки допустимости нажатия кнопки в форме для определенного пользователя.

Вы бы не хотели чтобы злоумышленник отправлял данные доступные только для админа.

public function authorize(): bool
{
    /* Retrieve the comment that the user wants to update */
    $comment = Comment::find($this->route('comment'));
 
    /* Check if the comment exists and if the user is allowed to update this   particular comment. If you want to learn more about the user()->can() method, you should checkout the Laravel docs on guards and authorization. */
    return $comment && $this->user()->can('update', $comment);
}

Как мы используем Form Requests?

Использование Form Requests очень простое. В вашем контроллере, похожем на код ниже, укажите вместо Request $request, StorePostRequest $request

use \App\Http\Requests\StorePostRequest;
 
public function store(StorePostRequest $request): mixed
{
    // The incoming request is valid...
    // else the Form Request would have returned the error messages and we wouldn't be here then.
 
    // Retrieve the validated input data...
    $validated = $request->validated();
}

Отображение ошибок идет по тому же пути что и в первом способе.

Настройка вывода сообщений ошибок в Form Request

Есть еще некоторые функций, которые мы можем добавить в наш Form Requests. Одна из них это функция messages(). Она позволяет настроить сообщения об ошибке для каждой формы, а не для всего приложения сразу:

public function messages(): array
{
    return [
        'title.required' => 'A title is required',
        'body.required' => 'A message is required',
    ];
}

Способ валидации 3: Ручное создание Validator::make()

Третий способ заключается в ручном созданий экземпляра Validator. Он не делает автоматическое перенаправление и возврат ошибок, но позволяет ловить и обрабатывать их как нравится. Это означает что вы получаете больше свободы в использований обработчика. Например:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
 
public function store(Request $request): mixed
{
    $validator = Validator::make($request->all(), [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);
 
    if ($validator->fails()) {
        // For example:
        return redirect('post/create')
                ->withErrors($validator)
                ->withInput();
 
        // Also handy: get the array with the errors
        $validator->errors();
 
        // or, for APIs:
        $validator->errors()->toJson();
    }
 
    // Input is valid, continue...
}

Определение правил

Как вы видели в примерах выше, для использования валидатора мы должны определять правила. Есть много правил, в списке ниже находятся самые популярные из них. Чтобы увидеть более обширный список обратитесь к документаций.

Здесь в наших примерах мы используем ‘pipe’ синтаксис ‘fieldname’: ‘rule|otherRule|anotherRule’. Но вы можете использовать синтаксис массивов: ‘fieldname’: [‘rule’, ‘otherRule’, ‘anotherRule’] .

Наиболее используемые правила валидации в Laravel

Обязательный ввод:

requiredrequired_if:anotherField,equalToThisValuerequired_unless:anotherField,equalToThisValue

Поля должны иметь определенные шаблоны(email):

emailactive_urlip.

Базы данных(уникальные и существующие записи):

exists:tableName,columnNameunique:tableName,columnName.

До и после определенной даты:

after:datebefore:date . Обратите внимание, что date должна быть строкой, с которой может работать strtotime().

Выводы

Как вы могли видеть, валидация (внешнего api) данных и пользовательского ввода в Laravel очень проста и есть несколько рабочих процессов. Каждый рабочий процесс имеет свой уровень “работы из коробки” или дает больший уровень свободы.

To top