Валидация

Содержание:

Введение

Laravel предоставляет несколько различных подходов для проверки входящих данных вашего приложения. По умолчанию, базовый контроллер Laravel использует трейт ValidatesRequests, который предоставляет метод проверки входящего запроса HTTP вместе с набором мощных правил валидации.


Быстрый старт

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

Определение маршрутов

Во-первых, давайте предположим, что у нас определены следующие маршруты в файле routes/web.php:

Route::get('post/create', 'PostController@create');

Route::post('post', 'PostController@store');

Маршрут с методом GET покажет форму создания новой заметки блога для пользователя, в то время как маршрут с POST сохранит новую заметку блога в базе данных.

Создание контроллера

Теперь, давайте взглянем на простой контроллер, который обрабатывает эти маршруты. Пока что оставим метод store пустым:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Show the form to create a new blog post.
     *
     * @return Response
     */
    public function create()
    {
        return view('post.create');
    }

    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // Validate and store the blog post...
    }
}

Написание логики

Теперь мы готовы заполнить метод store логикой обработки валидации новой заметки блога. Чтобы сделать это, мы используем метод validate предоставленным объектом Illuminate\Http\Request. Если данные запроса проходят через правила валидации, код продлжает выполняться в обычном режиме. Но если данные не прошли правила валидации, будет выдано исключение и ответ ввиде ошибки автоматически будет отправлен пользователю. В случае с традиционным запросами HTTP, будет сгенерирован ответ в виде перенаправления. А в случае с AJAX запросами, пользователь получит ответ JSON.

Для лучшего понимания метода validate, давайте вернёмся к методу store:

/**
 * Store a new blog post.
 *
 * @param  Request  $request
 * @return Response
 */
public function store(Request $request)
{
    $validatedData = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // The blog post is valid...
}

Как вы можете видеть, мы передали требуемые правила валидации в метод validate. Стоит повторить, что если проверка завершается неудачно, автоматически будет сгенерирован нужный ответ. А если данные запроса прошли валидацию, код контроллера будет выполняться в обычном режиме.

Как альтернатива, правила валидации можно указывать ввиде массива правил вместо разделённой строки:

$validatedData = $request->validate([
    'title' => ['required', 'unique:posts', 'max:255'],
    'body' => ['required'],
]);

Остановка на первой неудаче проверки

Иногда вы можете захотеть остановить выполнение правил валидации после первой неудачи на определённом шаге. Чтобы сделать так, добавьте правило bail к набору правил валидации:

$request->validate([
    'title' => 'bail|required|unique:posts|max:255',
    'body' => 'required',
]);

Правила валидации будут выполняться в том порядке, в котором указаны. В этом примере, если правило unique для аттрибута title провалится, правило max не будет выполняться.

Заметка о сгруппированных атрибутах

Если ваш запрос HTTP содержит сгруппированные параметры, вы можете указать правила валидации для каждого, используя синтаксии с точками:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',
]);

Вывод ошибок

Но что если параметры входящего запрос не проходят предложенные правила валидации? Как и упоминалось ранее, Laravel автоматически перенаправит пользователя, например на предыдущую страницу. В дополнение, все ошибки валидации автоматически будут переданы ввиде флеш-данных.

Обратите внимание на то, что нам не нужно явно привязывать сообщения ошибки к нашему представлению в маршруте GET. Всё потому, что Laravel проверяет данные сессии на ошибки валидации и автоматически привязывает их в представление, если ошибки есть. Переменная $errors будет экземпляром Illuminate\Support\MessageBag. Для информации о том, как работать с этим объектом, обратитесь к соответсвующей документации.

Переменная $errors привязана к представлению через посредника Illuminate\View\Middleware\ShareErrorsFromSession, из группы посредников web. Если такой посредник утверждён для маршрута, то переменная $error всегда будет доступна в вашем представлении, определена и её можно безопасно использовать.

Поэтому, в нашем примере, пользователь будет перенаправлен в метод контроллера create, если валидация провалилась. Это позволяет отображать сообщение об ошибке в представлении:

<!-- /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>
@endif
<!-- Create Post Form -->

The @error Директива

Вы также можете использовать директиву Blade @error, чтобы быстро проверить, что сообщение ошибки валидации существует для данного атрибута. Внутри директивы @error вы можете вывести переменную $message, чтобы показать сообщение ошибки:

<!-- /resources/views/post/create.blade.php -->

<label for="title">Post Title</label>

<input id="title" type="text" class="@error('title') is-invalid @enderror">

@error('title')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

Заметка о необязательных полях

По умолчанию, Laravel включает TrimStrings и ConvertEmptyStringsToNull в глобальный список посредников вашего приложения. Все эти посредники перечислены в классе App\Http\Kernel. Из-за этого, вам часто будет необходимо отмечать необязательные поля правилом nullable, если вы не хотите, чтобы валидатор признавал значение null некорректным. Например:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
    'publish_at' => 'nullable|date',
]);

В этом примере, мы указываем, что поле publish_at может быть null или датой. Если мы не добавим модификатор nullable к списку правил, то валидатор будет считать null неверными данными.

Запросы AJAX и валидация

В этом примере, мы использовали традиционную форму, чтобы выслать данные в приложение. Однако, многие прилжения используют запросы AJAX. При использовании метода validate в течение AJAX запроса, Laravel не будет генерировать ответ в виде перенаправления. Вместо этого, Laravel генерирует JSON ответ, который и содержит все ошибки валидации. Ответ JSON отправляется со статус кодом 422.


Валидация запроса формы

Создание формы запроса

Для более сложных сценариев валидации, вы можете создать "запрос формы". Запрос формы — это пользовательский класс, который содержит логику валидации. Чтобы создать такой класс, используйте команду Артизан make:request:

php artisan make:request StoreBlogPost

Сгенерированный класс будет располагаться в папке app/Http/Requests. Если такая папка не существует, она будет создана при выполнении команды make:request. Давайте добавим несколько правил валидации в метод rules:

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}
Вы можете вписать любые зависимости, которым вам нужны, внутри метода rules. Они автоматически будут внедрены через сервис контейнер.

Чтобы использовать правила валидации, необходимо вписать request в метод контроллера. Входящий запрос формы проходит валидацию до вызова метода контроллера. Это значит, что вам не нужно нагромождать контроллер логикой валидации:

/**
 * Store the incoming blog post.
 *
 * @param  StoreBlogPost  $request
 * @return Response
 */
public function store(StoreBlogPost $request)
{
    // The incoming request is valid...

    // Retrieve the validated input data...
    $validated = $request->validated();
}

Если валидация провалится, то ответ в виде перенаправления будет сгенерирован и отправлен назад пользователю в предыдущую локацию. Ошибки также будут добавлены во флеш-данные сессии и будут доступны для отображения. Если запрос был AJAX, то пользователю вернётся ответ со статус кодом 422, включая представление JSON об ошибках валидации.

Добавление слотов "после" в форму запросов

Если вы хотите добавить слот "после" в форму запроса, вы можете использовать метод withValidator. Этот метод получает полностью сконструированный валидатор, что позволяет вам вызывать любой из методов до фактического применения правил валидации:

/**
 * Configure the validator instance.
 *
 * @param  \Illuminate\Validation\Validator  $validator
 * @return void
 */
public function withValidator($validator)
{
    $validator->after(function ($validator) {
        if ($this->somethingElseIsInvalid()) {
            $validator->errors()->add('field', 'Something is wrong with this field!');
        }
    });
}

Авторизация запросов формы

Класс формы запроса также содержит метод authorize. Внутри этого метода вы можете проверить, что авторизованный пользователь имеет право обновлять данный ресурс. Например, вы можете определить, что пользователь пытается обновить свой комментарий:

/**
 * Determine if the user is authorized to make this request.
 *
 * @return bool
 */
public function authorize()
{
    $comment = Comment::find($this->route('comment'));

    return $comment && $this->user()->can('update', $comment);
}

Так как все запросы формы расширяют базовый класс запроса Ларавел, мы можем использовать метод user, чтобы получить доступ к текущему авторизированному пользователю.

Вызов метод route даёт доступ к URI параметрам, определённых на маршруте вызова, например, таких как {comment}:

Route::post('comment/{comment}');

Если метод authorize возвращает false, ответ HTTP со статус кодом 403 автоматически, а метод контроллера выполняться не будет.

Если вы планируете иметь логику авторизации в другой части вашего приложения, возвращайте true из метода authorize:

/**
 * Determine if the user is authorized to make this request.
 *
 * @return bool
 */
public function authorize()
{
    return true;
}
Вы можете вписать любые зависимости, которые вам нужны, в сигнатуре метода authorize. Они будут автоматически внедрены через сервис контейнер.

Настройка сообщений об ошибках

Вы можете настроить сообщения об ошибках из запроса формы путём переписывания метода messages. Этот метод должен вернуть массив пар атрибут / правило и соответсвующие сообщения об ошибке:

/**
 * Get the error messages for the defined validation rules.
 *
 * @return array
 */
public function messages()
{
    return [
        'title.required' => 'A title is required',
        'body.required'  => 'A message is required',
    ];
}

Настройка атрибутов валидации

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

/**
 * Get custom attributes for validator errors.
 *
 * @return array
 */
public function attributes()
{
    return [
        'email' => 'email address',
    ];
}

Создание валидаторов вручную

Если вы не хотите использовать метод validate дла запроса, вы можете создать экземпляр валидатора вручную, используя фасад Validator. Метод фасада make сгенерирует новый экземпляр:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;

class PostController extends Controller
{
    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);

        if ($validator->fails()) {
            return redirect('post/create')
                        ->withErrors($validator)
                        ->withInput();
        }

        // Store the blog post...
    }
}

Первый аргумент, который передаётся в метод make, это данные для валидации. Второй аргумент — это правила валидаци, которые должны применяться к данным.

После проверки валидации на неудачу, вы можете использовать метод withErrors, чтобы добавить сообщения об ошибках во флеш-данные в сессию. При использовании этого метода, переменная $errors автоматически будет доступна для представлений после перенаправлений, что позволяет легко показывать ошибки пользователю. Метод withErrors принимает валидатор MessageBag, или массив PHP.

Автоматическое перенаправление

Если вы хотите создать экзмепляр валидатора вручную, но одновременно с этим хотите получить преимущества авмтоматического перенаправления метода запроса validate, вы можете обратиться к методу validate к существующему экземпляру валидатора. Если валидация закончится неудачей, пользователь автоматически будет перенаправлен, а в случае с запросом AJAX, вернётся JSON ответ:

Validator::make($request->all(), [
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
])->validate();

Корзина названных ошибок

Если у вас несколько форм на одной странице, вы можете присвоить имя ошибкам из MessageBag, что позволит получить сообщение ошибки для определённой формы. Для этого передайте имя, как второй аргумент в withErrors:

return redirect('register')
            ->withErrors($validator, 'login');

Вы можете получить доступ к названному экзмемпляру MessageBag из переменной $errors:

{{ $errors->login->first('email') }}

Слот после валидации

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

$validator = Validator::make(...);

$validator->after(function ($validator) {
    if ($this->somethingElseIsInvalid()) {
        $validator->errors()->add('field', 'Something is wrong with this field!');
    }
});

if ($validator->fails()) {
    //
}

Работа с сообщениями об ошибках

После обращения к ошибкам экземпляра Validator, вы получите экземпляр Illuminate\Support\MessageBag, с набором удобных методов для работы с ошибками. Переменная $errors, которая автоматически доступна для всех представлений, также является экземпляром класса MessageBag.

Получение первого сообщения ошибки для поля

Чтобы получить первое сообщение об ошибке для данного поля, используйте метод first:

$errors = $validator->errors();

echo $errors->first('email');

Поучение всех сообщений об ошибке для поля

Если вам необходимо получить массив всех сообщений об ошибках для данного поля, используйте метод get:

foreach ($errors->get('email') as $message) {
    //
}

Если вы проводите валидацию поля значение содержимого которого является массивом, тогда вы можете получить все сообщения для каждого элемента массива, используя символ *:

foreach ($errors->get('attachments.*') as $message) {
    //
}

Получение всех сообщений об ошибке для всех полей

Чтобы получить все сообщения для всех полей, используйте метод all:

foreach ($errors->all() as $message) {
    //
}

Определить, что сообщение существует для поля

Метод has может быть использован, чтобы проверить на наличие ошибок валидации для данного поля:

if ($errors->has('email')) {
    //
}

Настройка сообщений об ошибке

Если необходимо, вы можете использовать пользовательские сообщедния вместо стандартных. Есть несколько способов указать пользовательские сообщения. Во-первых, вы можете передать ваше сообщение как третий аргумент в метод Validator::make:

$messages = [
    'required' => 'The :attribute field is required.',
];

$validator = Validator::make($input, $rules, $messages);

В этом примере, :attribute будет заменён актуальным именем поля валидации. Вы также можете задействовать другие заменители в сообщениях валидации. Например:

$messages = [
    'same'    => 'The :attribute and :other must match.',
    'size'    => 'The :attribute must be exactly :size.',
    'between' => 'The :attribute value :input is not between :min - :max.',
    'in'      => 'The :attribute must be one of the following types: :values',
];

Указание пользовательского сообщения для данного атрибута

Иногда, вы можете захотеть указать пользовательское сообщение только для конкретного поля. Вы можете сделать это используя сннтаксис с точками. Сперва указывается атрубут, а потом правило:

$messages = [
    'email.required' => 'We need to know your e-mail address!',
];

Указание пользовательских сообщений в языковых файлах

В большинстве случаев, вам необходимо указать ваши пользовательские сообщения в языковом файле вместо того, чтобы передавать их экземпляру Validator напрямую. Чтобы это сделать добавьте ваши сообщения в массив custom в файле языковом resources/lang/xx/validation.php.

'custom' => [
    'email' => [
        'required' => 'We need to know your e-mail address!',
    ],
],

Указание пользовательских атрибутов в языковых файлах

Если вы хотите, чтобы сегмент :attribute сообщения валидации был заменён на пользовательское имя, вы можете указать имя в массиве attributes файла локализации resources/lang/xx/validation.php:

'attributes' => [
    'email' => 'email address',
],

Настройка пользовательских значений в языковых файлах

Иногда может случиться так, что нужно заменить сегмент :value сообщения валидации на пользовательское представление значения. Например, требуется номер кредитной карты, если payment_type имеет значение cc:

$request->validate([
    'credit_card_number' => 'required_if:payment_type,cc'
]);

Если правило валидации закончится неудачей, будет написано следующее сообщение об ошибке:

The credit card number field is required when payment type is cc.

Вместо показа cc как значение типа оплаты, вы можете указать пользовательское значение представления в файле локализации validation путём определения массива values:

'values' => [
    'payment_type' => [
        'cc' => 'credit card'
    ],
],

Теперь, если правило валидации завершится провалом, получится такое сообщение:

The credit card number field is required when payment type is credit card.

Доступные правила валидации

Ниже представлен список доступных правил валидации и их функции:

  • Accepted
  • Active URL
  • After (Date)
  • After Or Equal (Date)
  • Alpha
  • Alpha Dash
  • Alpha Numeric
  • Array
  • Bail
  • Before (Date)
  • Before Or Equal (Date)
  • Between
  • Boolean
  • Confirmed
  • Date
  • Date Equals
  • Date Format
  • Different
  • Digits
  • Digits Between
  • Dimensions (Image Files)
  • Distinct
  • E-Mail
  • Ends With
  • Exists (Database)
  • File
  • Filled
  • Greater Than
  • Greater Than Or Equal
  • Image (File)
  • In
  • In Array
  • Integer
  • IP Address
  • JSON
  • Less Than
  • Less Than Or Equal
  • Max
  • MIME Types
  • MIME Type By File Extension
  • Min
  • Not In
  • Not Regex
  • Nullable
  • Numeric
  • Present
  • Regular Expression
  • Required
  • Required If
  • Required Unless
  • Required With
  • Required With All
  • Required Without
  • Required Without All
  • Same
  • Size
  • Sometimes
  • Starts With
  • String
  • Timezone
  • Unique (Database)
  • URL
  • UUID
accepted

Поле валидации должно быть "yes", "on", "1", or "true". Может быть полезно для валидации "условий предоставления услуг".

active_url

Поле валидации должно иметь валидную запись A или AAAA в соответствии с функцией PHP dns_get_record.

after:date

Поле валидации должно быть значением даты после представленной даты. Даты будут переданы в функцию PHP strtotime:

'start_date' => 'required|date|after:tomorrow'

Instead of passing a date string to be evaluated by strtotime, you may specify another field to compare against the date:

'finish_date' => 'required|date|after:start_date'
after_or_equal:date

Поле валидации должно быть датой после или равнятьс данной даты. Для большей информации, смотрите правило after.

alpha

Поле валидации должно состоять исключительно из буквенных символов.

alpha_dash

Поле валидации должно состоять из буквенных символом, тире или нижнего подчёркивания.

alpha_num

Поле валидации должно состоять из букв или цифр.

array

Поле валидации должно быть массивом PHP.

bail

Остановить выполнение валидации после первой неудачной валидации.

before:date

Поле валидации должно быть датой до выбранного числа. Даты будут передаваться в функцию PHP strtotime.

before_or_equal:date

Поле валидации должно быть датой до выбранного числа или быть равным определённой даты. Даты будут передавать в функцию PHP strtotime.

between:min,max

Поле валидации должно иметь размер между выбранным минимумом и максимумом. Строки, числа, массивы и файлы оцениваются одинаково, как правило валидации для размера.

boolean

Значение поля валидации можно привести к логическому. Допустимые значения true, false, 1, 0, "1", и "0".

confirmed

Поле валидации должно соответсвовать полю "foo_confirmation". Например, если поле валидации "password", соответствующее поле "password_confirmation" должно присутствовать среди вводных полей.

date

Значение поля валидации должно быть действительной, не относительной датой, как для функции PHP strtotime.

date_equals:date

Поле валидации должно быть равным данной дате. Даты будут передаваться в функцию PHP strtotime.

date_format:format

Значение поля валидации должно соответствовать данному формату. Вы должны использовать либо date или date_format при валидации, но не оба формата сразу. Это правило валидации поддерживает все форматы класса DateTime языка PHP.

different:field

Значение поля валидации должно отличаться от значения поля.

digits:value

Значение поля валидации должно быть числовым и должно быть точно длины.

digits_between:min,max

Длина значения поля валидации должно быть между минимальным и максимальным значениями.

dimensions

Файл валидации должен быть изображением и удовлетворять условиям, указанным в параметрах правила:

'avatar' => 'dimensions:min_width=100,min_height=200'

Доступные дополнительные параметры: min_width, max_width, min_height, max_height, width, height, ratio.

Дополнительный параметр ratio должен быть представлен как отношение ширины к высоте. Значение может быть числом или действием деления, например 3/2 или 1.5:

'avatar' => 'dimensions:ratio=3/2'

В силу того. что правило требует несколько аргументов, вы можете использовать метод Rule::dimensions для построения правила:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'avatar' => [
        'required',
        Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
    ],
]);
distinct

При работе с массивами, поле валидации не должно иметь дубликатов.

'foo.*.id' => 'distinct'
email

Поле валидации должно быть e-mail адресом. Механизм работы основана на компоненте egulias/email-validator для валидации электронной почты. По умолчанию, задействован валидатор RFCValidation, но можно легко добавить и другие валидаторы:

'email' => 'email:rfc,dns'

Пример выше включает валидаторы RFCValidation и DNSCheckValidation. Полный список доступных стилей валидации:

  • rfc: RFCValidation
  • strict: NoRFCWarningsValidation
  • dns: DNSCheckValidation
  • spoof: SpoofCheckValidation
  • filter: FilterEmailValidation

Валидатор filter использует функцию PHP filter_var и включён в стандартную сборку Ларавел.

ends_with:foo,bar,...

Поле валидации должно заканчиваться одним из предложенных значений.

exists:table,column

Поле валидации должно быть существующей таблицей базы данных. Типовое использование:

'state' => 'exists:states'

Если не указан параметр названия колонки, тогда будет использовано имя поля.

Указание пользовательского имени колонки
'state' => 'exists:states,abbreviation'

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

'email' => 'exists:connection.staff,email'

Если вы хотите настроить запрос, который выполняется правилом валидации, вы можете использовать класс Rule, чтобы определить правило. В этом примере, мы также указываем правила валидации как массив вместо использования символа | для их разделения:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::exists('staff')->where(function ($query) {
            $query->where('account_id', 1);
        }),
    ],
]);
file

Поле валидации должно быть успешно загруженным файлом.

filled

Поле валидации должно быть не пустым.

gt:field

Поле валидации должно быть больше, чем указанное поле. Два поля должны быть одинаковаго типа. Строки, числа, массивы и файлы оцениваются по тем же критериям, что и правило size.

gte:field

Поле валидации должно быть больше или равно данного поля. Оба поля должны быть одинакового типа. Строки, числа, массивы и файлы оцениваются по тем же критериям, что и правило size.

image

Файл валидации должен быть изображением (jpeg, png, bmp, gif, svg, or webp).

in:foo,bar,...

Поле валидации должно должно соответствовать одному из данных значений. Поскольку правило часто требует от вас разбить массив, метод Rule::in можно использовать для построения правила:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'zones' => [
        'required',
        Rule::in(['first-zone', 'second-zone']),
    ],
]);
in_array:anotherfield.*

Значение поля валидации должно существовать в другом значении поля.

integer

Поле валидации должно быть целым числом.

Это правило валидации не проводит верификацию того, что поле является типом переменной "integer", а только, что вводное значение строка или числовое значение, которое содержить целое число.
ip

Поле валидации должжно быть IP адресом.

ipv4

Поле валидации должжно быть IPv4 адресом.

ipv6

Поле валидации должжно быть IPv6 адресом.

json

Поле валидации должно быть валидной JSON строкой.

lt:field

Поле валидации должно быть меньше чем данное поле. Оба поля должны быть одинакового типа. Строки, числа, массивы и файлы оцениваются по тем же критериям, что и правило size.

lte:field

Поле валидации должно быть меньше или равно заданному полю. Оба поля должны быть одинакового типа. Строки, числа, массивы и файлы оцениваются по тем же критериям, что и правило size.

max:value

Поле валидации должно быть меньше или равно максимальному значению. Строки, числа, массивы и файлы оцениваются по тем же критериям, что и правило size.

mimetypes:text/plain,...

Файл валидации должен соответсвовать одному из данных MIME типов:

'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'

Чтобы определить MIME тип для загруженного файла, содержание файла будет прочитано и проанализировано фреймворком, после чего будет предпринята попытка угать к какому MIME типу отнести файл. Этот тип может отличаться от MIME типа клиента.

mimes:foo,bar,...

Файл валидации должен иметь тип MIME, который соответсвует одному из представленных в списке.

Типовое использование MIME правила
'photo' => 'mimes:jpeg,bmp,png'

Даже если вам необходимо лишь указать расширения, правило фактически проверяет MIME тип файла путём чтения содержания файла и угадывает тип MIME.

Полный списаок MIME типов и соответствующих расширений можно найти по следующей ссылке: https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types

min:value

Поле валидации должно иметь минимальное значение. Строки, числа, массивы и файлы оцениваются как правило size.

not_in:foo,bar,...

Значение поля валидации не должно быть в указанном списке. Метод Rule::notIn можно использовать для построения правила:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'toppings' => [
        'required',
        Rule::notIn(['sprinkles', 'cherries']),
    ],
]);
not_regex:pattern

Поле валидации не должно соответсвовать указанному паттерну.

Это правило использует функцию PHP preg_match. Указанный паттерн должен соответствовать такому же форматированию, что и требуется для preg_match, дополнительно включает допустимые разделители. Например, 'email' => 'not_regex:/^.+$/i'.

При использовании паттернов regex / not_regex может быть нужно указать правила в массиве, вместо использования резделителей. Особенно если разделители используются в регулярном выражении.

nullable

Поле валидации можеть быть null. Применяется для того, чтобы обойти посредников TrimStrings и ConvertEmptyStringsToNull.

numeric

Поле валидации должно быть числовым.

present

Поле валидации должно присутсвовать в данных ввода, но может быть и пустым.

regex:pattern

Поле валидации должно соответсвовать данному регулярному выражению.

Под капотом, правило использует функцию PHP preg_match. Указанный паттерн должен соответсвтовать форматированию preg_match и включать разрешённые разделители. Например: 'email' => 'regex:/^.+@.+$/i'.

При использовании паттернов regex / not_regex может быть необходимо указать правила в массиве, вместо использования разделителей. Особенно когда регулярное выражение использует символ-разделитель.

required

Поле валидации должно присутствовать в данных ввода и не должно быть пустым. Поле считается "пустым" если выполняется одно из условий:

  • Значение поля null.
  • Значение поля пустая строка.
  • Значение поля пустой массив или пустой счётный объект.
  • Значение поля загруженный файл без пути.
required_if:anotherfield,value,...

Поле валидации должно присутствовать и быть не пустым, значение другого поля равно любому значению.

Если вы хотите построить более сложное условие для правила required_if, можно использовать метод Rule::requiredIf. Правило применяет логическое или замыкание. При передаче замыкания, оно должно возвращать true или false:

use Illuminate\Validation\Rule;

Validator::make($request->all(), [
    'role_id' => Rule::requiredIf($request->user()->is_admin),
]);

Validator::make($request->all(), [
    'role_id' => Rule::requiredIf(function () use ($request) {
        return $request->user()->is_admin;
    }),
]);
required_unless:anotherfield,value,...

Поле валидации должно присутсвовать и не должно быть пустым, до тех пор другое поле равняется любому значению.

required_with:foo,bar,...

Поле валидации должно присутствовать и не быть пустым, только если любое из указанных полей присутствует.

required_with_all:foo,bar,...

Поле валидации должно присутствовать и не должно быть пустым, только если все остальные указанные поля присутствуют.

required_without:foo,bar,...

Поле валидации должно присутствовать и не должно быть пустым, только если любое из остальных указанных полей не присутствует.

required_without_all:foo,bar,...

Поле валидации должно присутствовать и не должно быть пустым, только если все указанные поле не присутствуют.

same:field

Данное поле должно соответствовать полю валидации.

size:value

Проверяемое поле должно иметь размер, соответствующий заданному значению. Для строковых данных значение соответствует количеству символов. Для числовых данных значение соответствует заданному целочисленному значению. Для массива размер соответствует количеству элементов массива. Для файлов, размер соответствует размеру файла в килобайтах.

starts_with:foo,bar,...

Поле валидации должно начинаться с одного из представленных значений.

string

Поле валидации должно быть строкой. Чтобы значение поля могло быть null, нужно добавить правило nullable.

timezone

Поле валидации должно быть правильным идентификатором часового пояса в соответсвии с функцией PHP timezone_identifiers_list PHP.

unique:table,column,except,idColumn

Поле валидации не должно существовать внутри данной таблицы базы данных.

Указание пользовательского имени столбца.

>

Такую опцию можно использовать, чтобы указать какая какой столбец базы данных соответсвует полю. Если ничего не указано, будет использовано имя поля.

'email' => 'unique:users,email_address'

Пользовательское соединение с базой данных

Может так случится, что вам необходимо установить пользовательское соединение для запросов базы данных, сделанных валидатором. Для этого необходимо указать соединение и таблицу используя синтаксис с точками:

'email' => 'unique:connection.users,email_address'

Правило Unique игнорирует определёный идентификатор:

Иногда вам может потребоваться проигнорировать определённый идентификатор в процессе проверки на уникальность. Например, у нас есть поля имя, e-mail, локация дли страницы "Обновить профиль". Вам скорее всего потребуется проверить, что e-mail уникальный. Но если пользователь изменил только имя, а не e-mail, электронная почта будет неуникальной. Ввы не захотите появления ошибки валидации из-за этого.

Чтобы научить валидатор игнорировать идентификатор пользователя, мы будем использовать класс Rule, чтобы определить правило. В этом примере, мы также указываем правила валидации как массив вместо использования знака | для разделения правил:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);
Вы не должны передавить методу данные запроса подконтрольные пользователю. Вместо этого, вы должны только передать сгенерированный системой уникальный идентификатор, такой как автоинкремент ID или UUID из экземпляра модели Eloquent. В противном случае, приложение может быть уязвимым для SQL инъекции.

Вместо передачи в модель значение ключа, вы можете передать вы можете передать весь экземпляр модели. Ларавел автоматически извлечёт ключ из модели:

Rule::unique('users')->ignore($user)

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

Rule::unique('users')->ignore($user->id, 'user_id')

По умолчанию, правило unique будет проверять уникальность имя атрибута. Однако, вы можете передать другое имя колонки, как второй аргумент в метод unique:

Rule::unique('users', 'email_address')->ignore($user->id),

Добавление дополнительных условий:

Можно также задать дополнительные ограничения запроса, используя метод where и настроки запроса. Например, давайте добавим ограничение, которое проверяет, что account_id равен 1:

'email' => Rule::unique('users')->where(function ($query) {
    return $query->where('account_id', 1);
})
url

Поле валидации должно быть URL.

uuid

Поле валидации должно быть правильным RFC 4122 (версии 1, 3, 4, или 5) универсальным уникальным идентификатором (UUID).


Добавление правил при соблюдении условий

Валидация при наличии

В некоторых ситуациях, вы можете захотеть запустить проверку поля, но только в том случае, когда оно присутсвует во входном массиве. Чтобы сделать это, добавьте правило sometimes в ваш список правил:

$v = Validator::make($data, [
    'email' => 'sometimes|required|email',
]);

В примере выше, поле email будет проверено если присутсвует в массиве $data.

Если вы пытаетесь провести валидацию поля, которое должно всегда присутствовать, но может быть пустым, тогда перечитайте информацию про необязательные поля.

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

Иногда вы можете хотеть добавить правила валидации, основанные на более сложной логике и при выполнении определённых условий. Например, вы хотите чтобы поле было обязательным только если другое поле имеет значение больше 100. Или, например, вы хотите чтобы 2 поля имели данное значение при наличии другого поля. Добавление такой валидации не должно быть болью. Во-первых, создайте экземпляр Validator с вашими статичными правилами, которые не меняются:

$v = Validator::make($data, [
    'email' => 'required|email',
    'games' => 'required|numeric',
]);

Давайте предположим, что наше приложение для коллекционеров игр. Если коллекционер регистрируется в нашем приложении и владеет больше 100 игр, мы хотим чтобы они объяснили почему у них так много игр. Например, предположим, что они магазином по продаже игр, или им просто нравится коллекционировать. Для того чтобы добавить это требование, мы можем использовать метод sometimes на экзмепляр Validator.

$v->sometimes('reason', 'required|max:500', function ($input) {
    return $input->games >= 100;
});

Первый аргумент, передоваемого в метод sometimes, это имя поля, которое мы проверяем при определённом условии. Вторым аргументом является правило, которое мы хотим добавить. Если Closure, которое передаётся как третий аргумент, возвращает true, другие правила будут добавлены. С помощью такого метода можно вздохнуть с облегчением при построении сложной валидации с условиями. Вы даже можете проводить условную валидацию для нескольких полей одновременно:

$v->sometimes(['reason', 'cost'], 'required', function ($input) {
    return $input->games >= 100;
});
Передаваемый в замыкание параметр $input будет экземпляром Illuminate\Support\Fluent и может быть использован для доступа к данным ввода и файлам.

Валидация массивов

Вы также легко можете проводить валидацию массивов. Для этого нужно использовать синтаксис с точками, чтобы провести валидацию атрибутов в массиве. Например, если входящий запрос HTTP содержит поле photos[profile], вы можете провдить валидацию таким образом:

$validator = Validator::make($request->all(), [
    'photos.profile' => 'required|image',
]);

Вы также можете провести валидацию каждого элемента массива. Например, чтобы проверить каждый e-mail в массиве на уникальность, вам нужно сделать следующее:

$validator = Validator::make($request->all(), [
    'person.*.email' => 'email|unique:users',
    'person.*.first_name' => 'required_with:person.*.last_name',
]);

Вы можете использовать символ * при указании сообщений валидации в файле локализации. Это делает легким использование простых сообщений валидации для массива:

'custom' => [
    'person.*.email' => [
        'unique' => 'Each person must have a unique e-mail address',
    ]
],

Настройка правил валидации

Использование правил объектов

Laravel даёт набор полезных правил валидации. Однако, вы можете указать ваше собственное. Чтобы сгенерировать новое правило, используйте команду Artisan make:rule. Давайте использовать команду, чтобы сгенерировать правило. Правило будет проверять строку на то, чтобы все буквы были заглавными. Laravel разместит новое правило в папке app/Rules:

php artisan make:rule Uppercase

После создания правила, мы готовы определить его поведение. Правило содержит два метода: passes и message. Метод passes получает значение атрибута и имя, и должен вернуть true или false в зависимости от того, что значение атрибута проходит или нет. Метод message должен возвращать сообщение ошибки валидации, которое используется при неудачной валидации:

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Uppercase implements Rule
{
    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return strtoupper($value) === $value;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The :attribute must be uppercase.';
    }
}

Вы можете вызвать помощник trans из метода message, если вы хотите вернуть сообщение ошибки из файла перевода:

/**
 * Get the validation error message.
 *
 * @return string
 */
public function message()
{
    return trans('validation.uppercase');
}

После создания правила, вы можете прикрепить его к валидатору. Для этого передайте экземпляр правила объекта с вашими другими правилами валидации:

use App\Rules\Uppercase;

$request->validate([
    'name' => ['required', 'string', new Uppercase],
]);

Использование замыканий

Если вам нужно одиночное правило, а не правило для всего приложения, вы можете использовать замыкание вместо объекта. Замыкание получает имя атрибута, его значеине и обратную связь $fail, которая должна запускаться при неудачной валидации:

$validator = Validator::make($request->all(), [
    'title' => [
        'required',
        'max:255',
        function ($attribute, $value, $fail) {
            if ($value === 'foo') {
                $fail($attribute.' is invalid.');
            }
        },
    ],
]);

Использование расширений

Другой метод регистрации пользовательских правил заключается в использовании метод extend для фасада Validator. Давайте используем этот метод внутри сервис провайдера для регистрации пользовательского правила валидации:

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
            return $value == 'foo';
        });
    }
}

Пользовательский валидатор получает 4 аргумента: имя атрибута валидации $attribute, значение атрибута $value, массив параметров $parameters, и экзмепляр Validator.

Вы также можете передовать класс и метод в метод extend вместо замыкания:

Validator::extend('foo', 'FooValidator@validate');

Определение сообщения ошибки

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

"foo" => "Your input was invalid!",

"accepted" => "The :attribute must be accepted.",

// The rest of the validation error messages...

При создании пользовательского правила валидации, вам иногда может потребоваться сделать замену заполнителю для ошибок валидации. Вы можете сделать так путём создания пользовательского валидатора, как описано выше. Далее необходимо вызвать метод replacer на фасад Validator. Это нужно сделать внутри метода boot сервис провайдера:

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Validator::extend(...);

    Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {
        return str_replace(...);
    });
}

Неявные расширения

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

$rules = ['name' => 'unique:users,name'];

$input = ['name' => ''];

Validator::make($input, $rules)->passes(); // true

При выполнения правила, даже если атрибут пуст, подразумевается, что атрибут является обязательным. Чтобы создать такое "неявное" расширение, используйте метод Validator::extendImplicit():

Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
    return $value == 'foo';
});
Неявное расширение подразумевает только то, что атрибут является обязательным. Так ли это на самом деле, его нет или атрибут пуст, зависит от вас.

Скрытое правило объектовImplicit Rule Objects

Если вы хотите, чтобы правило валидации выполнялось при пустом атрибуте, вы должны расширить интерфейс Illuminate\Contracts\Validation\ImplicitRule. Это своего рода метка для валидатора, он не содержит методов для расширения.