1. Основы
  2. Валидация

Введение

Laravel предоставляет несколько различных подходов к валидации входящих данных вашего приложения. Самым распространенным способом является использование метода validate, доступного для всех входящих HTTP-запросов. Однако мы также обсудим и другие подходы к валидации.

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

Быстрый старт валидации

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

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

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

use App\Http\Controllers\PostController;
 
Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);

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

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

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

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
 
class PostController extends Controller
{
/**
* Показать форму для создания нового блог-поста.
*/
public function create(): View
{
return view('post.create');
}
 
/**
* Сохранить новый блог-пост.
*/
public function store(Request $request): RedirectResponse
{
// Проверить и сохранить блог-пост...
 
$post = /** ... */
 
return to_route('post.show', ['post' => $post->id]);
}
}

Написание логики валидации

Теперь мы готовы заполнить наш метод store логикой для валидации нового блог-поста. Для этого мы будем использовать метод validate, предоставленный объектом Illuminate\Http\Request. Если правила валидации пройдут, ваш код будет выполняться как обычно. Однако, если валидация не пройдет, будет выброшено исключение Illuminate\Validation\ValidationException, и пользователю автоматически будет отправлен соответствующий ответ с ошибками.

Если валидация не проходит во время традиционного HTTP-запроса, будет создано перенаправление на предыдущий URL. Если входящий запрос является XHR-запросом, будет возвращен JSON-ответ с сообщениями об ошибках валидации.

Чтобы лучше понять метод validate, давайте вернемся к методу store:

/**
* Сохранить новый блог-пост.
*/
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
 
// Блог-пост действителен...
 
return redirect('/posts');
}

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

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

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

Кроме того, вы можете использовать метод validateWithBag для валидации запроса и сохранения любых сообщений об ошибках в именованном мешке ошибок:

$validatedData = $request->validateWithBag('post', [
'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',
]);

С другой стороны, если ваше имя поля содержит буквальную точку, вы можете явно предотвратить ее интерпретацию как синтаксис "точка", экранировав точку обратной косой чертой:

$request->validate([
'title' => 'required|unique:posts|max:255',
'v1\.0' => 'required',
]);

Отображение ошибок валидации

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

Переменная $errors доступна во всех представлениях вашего приложения благодаря промежуточному программному обеспечению Illuminate\View\Middleware\ShareErrorsFromSession, предоставляемому группой промежуточного программного обеспечения web. Когда это промежуточное программное обеспечение применяется, переменная $errors всегда будет доступна в ваших представлениях, что позволяет удобно предполагать, что переменная $errors всегда определена и может быть безопасно использована. Переменная $errors будет экземпляром Illuminate\Support\MessageBag. Для получения дополнительной информации о работе с этим объектом, ознакомьтесь с его документацией.

Таким образом, в нашем примере, при неудачной валидации пользователь будет перенаправлен на метод 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>
</div>
@endif
 
<!-- Create Post Form -->

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

Встроенные правила валидации Laravel имеют сообщение об ошибке, которое находится в файле lang/en/validation.php вашего приложения. Если у вашего приложения нет каталога lang, вы можете указать Laravel создать его с помощью команды Artisan lang:publish.

В файле lang/en/validation.php вы найдете запись перевода для каждого правила валидации. Вы вольны изменять или модифицировать эти сообщения в соответствии с потребностями вашего приложения.

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

Внимание По умолчанию в скелете приложения Laravel отсутствует каталог lang. Если вы хотите настроить языковые файлы Laravel, вы можете опубликовать их с помощью команды Artisan lang:publish.

XHR-запросы и валидация

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

Директива @error

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

<!-- /resources/views/post/create.blade.php -->
 
<label for="title">Post Title</label>
 
<input id="title"
type="text"
name="title"
class="@error('title') is-invalid @enderror">
 
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror

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

<input ... class="@error('title', 'post') is-invalid @enderror">

Восполнение форм

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

Чтобы получить сохраненный в предыдущем запросе ввод, вызовите метод old у экземпляра Illuminate\Http\Request. Метод old извлечет ранее сохраненные данные ввода из сессии:

$title = $request->old('title');

Laravel также предоставляет глобальный помощник old. Если вы отображаете старый ввод в шаблоне Blade, удобнее использовать помощник old для восстановления формы. Если для заданного поля нет старого ввода, будет возвращено null:

<input type="text" name="title" value="{{ old('title') }}">

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

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

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

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

Формат ответа об ошибке валидации

Когда ваше приложение генерирует исключение Illuminate\Validation\ValidationException, и входящий HTTP-запрос ожидает JSON-ответа, Laravel автоматически форматирует сообщения об ошибках и возвращает HTTP-ответ с кодом состояния 422 Unprocessable Entity.

Ниже вы можете ознакомиться с примером формата JSON-ответа для сообщений об ошибках валидации. Обратите внимание, что вложенные ключи ошибок упрощаются в формате "точечной" нотации:

{
"message": "The team name must be a string. (and 4 more errors)",
"errors": {
"team_name": [
"The team name must be a string.",
"The team name must be at least 1 characters."
],
"authorization.role": [
"The selected authorization.role is invalid."
],
"users.0.email": [
"The users.0.email field is required."
],
"users.2.email": [
"The users.2.email must be a valid email address."
]
}
}

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

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

Для более сложных сценариев валидации может потребоваться создать "форму запроса". Формы запроса - это пользовательские классы запросов, которые инкапсулируют свою собственную логику валидации и авторизации. Чтобы создать класс формы запроса, вы можете использовать команду Artisan CLI make:request:

php artisan make:request StorePostRequest

Сгенерированный класс формы запроса будет помещен в каталог app/Http/Requests. Если этот каталог не существует, он будет создан при выполнении команды make:request. Каждая форма запроса, сгенерированная Laravel, имеет два метода: authorize и rules.

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

/**
* Получить правила валидации, применяемые к запросу.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}

Примечание Вы можете указать зависимости, которые вам необходимы, в сигнатуре метода rules. Они будут автоматически разрешены через контейнер зависимостей Laravel.

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

/**
* Сохранить новый блог-пост.
*/
public function store(StorePostRequest $request): RedirectResponse
{
// Входящий запрос действителен...
 
// Получить проверенные данные ввода...
$validated = $request->validated();
 
// Получить часть проверенных данных ввода...
$validated = $request->safe()->only(['name', 'email']);
$validated = $request->safe()->except(['name', 'email']);
 
// Сохранить блог-пост...
 
return redirect('/posts');
}

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

Примечание Нужно добавить валидацию формы в реальном времени к вашему фронтенду Laravel с использованием Inertia? Посмотрите Laravel Precognition.

Дополнительная валидация

Иногда вам нужно выполнить дополнительную валидацию после завершения первоначальной валидации. Это можно сделать с использованием метода after формы запроса.

Метод after должен вернуть массив вызываемых или замыканий, которые будут вызваны после завершения валидации. Предоставленные вызываемые получат экземпляр Illuminate\Validation\Validator, позволяя вам добавить дополнительные сообщения об ошибках, если это необходимо:

use Illuminate\Validation\Validator;
 
/**
* Получить "после" вызываемые валидации для запроса.
*/
public function after(): array
{
return [
function (Validator $validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add(
'field',
'Something is wrong with this field!'
);
}
}
];
}

Как отмечено ранее, массив, возвращаемый методом after, может также содержать классы, вызываемые. Метод __invoke этих классов получит экземпляр Illuminate\Validation\Validator:

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;
use Illuminate\Validation\Validator;
 
/**
* Получить "после" вызываемые валидации для запроса.
*/
public function after(): array
{
return [
new ValidateUserStatus,
new ValidateShippingTime,
function (Validator $validator) {
//
}
];
}

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

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

/**
* Определяет, должен ли валидатор остановиться при первом нарушении правила.
*
* @var bool
*/
protected $stopOnFirstFailure = true;

Настройка места перенаправления

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

/**
* URI, на который пользователей следует перенаправить, если валидация не удалась.
*
* @var string
*/
protected $redirect = '/dashboard';

Или, если вы хотите перенаправить пользователей на именованный маршрут, вы можете определить свойство $redirectRoute вместо этого:

/**
* Маршрут, на который пользователей следует перенаправить, если валидация не удалась.
*
* @var string
*/
protected $redirectRoute = 'dashboard';

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

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

use App\Models\Comment;
 
/**
* Определить, может ли пользователь делать этот запрос.
*/
public function authorize(): bool
{
$comment = Comment::find($this->route('comment'));
 
return $comment && $this->user()->can('update', $comment);
}

Поскольку все формы запроса расширяют базовый класс запроса Laravel, мы можем использовать метод user для доступа к текущему аутентифицированному пользователю. Также обратите внимание на вызов метода route в приведенном выше примере. Этот метод предоставляет доступ к параметрам URI, определенным в вызываемом маршруте, таким как параметр {comment} в приведенном ниже примере:

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

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

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

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

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

/**
* Определить, может ли пользователь делать этот запрос.
*/
public function authorize(): bool
{
return true;
}

Примечание Вы можете указать типы зависимостей, которые вам нужны, в сигнатуре метода authorize. Они будут автоматически разрешены через контейнер зависимостей Laravel.

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

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

/**
* Получить сообщения об ошибках для определенных правил валидации.
*
* @return array<string, string>
*/
public function messages(): array
{
return [
'title.required' => 'A title is required',
'body.required' => 'A message is required',
];
}

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

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

/**
* Получить пользовательские атрибуты для ошибок валидатора.
*
* @return array<string, string>
*/
public function attributes(): array
{
return [
'email' => 'email address',
];
}

Подготовка ввода для валидации

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

use Illuminate\Support\Str;
 
/**
* Подготовить данные для валидации.
*/
protected function prepareForValidation(): void
{
$this->merge([
'slug' => Str::slug($this->slug),
]);
}

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

/**
* Обработать успешную попытку валидации.
*/
protected function passedValidation(): void
{
$this->replace(['name' => 'Taylor']);
}

Ручное создание валидаторов

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

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
 
class PostController extends Controller
{
/**
* Сохранить новый блог-пост.
*/
public function store(Request $request): RedirectResponse
{
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
 
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
 
// Получить проверенный ввод...
$validated = $validator->validated();
 
// Получить часть проверенных данных ввода...
$validated = $validator->safe()->only(['name', 'email']);
$validated = $validator->safe()->except(['name', 'email']);
 
// Сохранить блог-пост...
 
return redirect('/posts');
}
}

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

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

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

Метод stopOnFirstFailure информирует валидатор, что он должен прекратить валидацию всех атрибутов после первой ошибки валидации:

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

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

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

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

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

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

Именованные мешки ошибок

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

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

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

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

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

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

$validator = Validator::make($input, $rules, $messages = [
'required' => 'The :attribute field is required.',
]);

В этом примере заполнитель :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 email address!',
];

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

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

$validator = Validator::make($input, $rules, $messages, [
'email' => 'email address',
]);

Дополнительная валидация

Иногда вам нужно выполнить дополнительную валидацию после завершения первоначальной валидации. Вы можете сделать это с помощью метода after валидатора. Метод after принимает замыкание или массив вызываемых, которые будут вызваны после завершения валидации. Переданные вызываемые получат экземпляр Illuminate\Validation\Validator, позволяя вам вызывать дополнительные сообщения об ошибках при необходимости:

use Illuminate\Support\Facades\Validator;
 
$validator = Validator::make(/* ... */);
 
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add(
'field', 'Something is wrong with this field!'
);
}
});
 
if ($validator->fails()) {
// ...
}

Как отмечалось ранее, метод after также принимает массив вызываемых, что особенно удобно, если ваша логика "после валидации" инкапсулирована в классах, которые можно вызвать, и которые получат экземпляр Illuminate\Validation\Validator через свой метод __invoke:

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;
 
$validator->after([
new ValidateUserStatus,
new ValidateShippingTime,
function ($validator) {
// ...
},
]);

Работа с проверенным вводом

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

$validated = $request->validated();
 
$validated = $validator->validated();

В качестве альтернативы вы можете вызвать метод safe на экземпляре формы запроса или валидатора. Этот метод возвращает экземпляр Illuminate\Support\ValidatedInput. Этот объект предоставляет методы only, except и all для извлечения подмножества валидированных данных или целого массива валидированных данных:

$validated = $request->safe()->only(['name', 'email']);
 
$validated = $request->safe()->except(['name', 'email']);
 
$validated = $request->safe()->all();

Кроме того, экземпляр Illuminate\Support\ValidatedInput можно итерировать и обращаться к нему как к массиву:

// Проверенные данные можно перебирать...
foreach ($request->safe() as $key => $value) {
// ...
}
 
// Проверенные данные можно обращаться как к массиву...
$validated = $request->safe();
 
$email = $validated['email'];

Если вы хотите добавить дополнительные поля к валидированным данным, вы можете вызвать метод merge:

$validated = $request->safe()->merge(['name' => 'Taylor Otwell']);

Если вы хотите извлечь валидированные данные в виде коллекции, вы можете вызвать метод collect:

$collection = $request->safe()->collect();

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

После вызова метода errors на экземпляре 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')) {
// ...
}

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

Встроенные правила валидации Laravel каждое имеют сообщение об ошибке, которое находится в файле lang/en/validation.php вашего приложения. Если в вашем приложении нет каталога lang, вы можете указать Laravel создать его с помощью команды Artisan lang:publish.

Внутри файла lang/en/validation.php вы найдете запись перевода для каждого правила валидации. Вы можете свободно изменять или модифицировать эти сообщения в соответствии с потребностями вашего приложения:

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

Внимание По умолчанию в скелете приложения Laravel отсутствует каталог lang. Если вы хотите настроить языковые файлы Laravel, вы можете опубликовать их с помощью команды Artisan lang:publish.

Пользовательские сообщения для конкретных атрибутов

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

'custom' => [
'email' => [
'required' => 'We need to know your email address!',
'max' => 'Your email address is too long!'
],
],

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

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

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

Внимание По умолчанию в скелете приложения Laravel отсутствует каталог lang. Если вы хотите настроить языковые файлы Laravel, вы можете опубликовать их с помощью команды Artisan lang:publish.

Указание значений в файлах языков

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

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

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

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

Вместо отображения cc в качестве значения типа платежа вы можете указать более понятное представление значения в вашем файле языка валидации lang/xx/validation.php, определив массив values:

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

Внимание По умолчанию в скелете приложения Laravel отсутствует каталог lang. Если вы хотите настроить языковые файлы Laravel, вы можете опубликовать их с помощью команды Artisan lang:publish.

После определения этого значения правило валидации выдаст следующее сообщение об ошибке:

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

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

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

accepted

Поле, проходящее валидацию, должно быть \"yes\", \"on\", 1 или true. Это полезно для проверки согласия с "Условиями обслуживания" или подобными полями.

accepted_if:anotherfield,value,...

Поле, проходящее валидацию, должно быть \"yes\", \"on\", 1 или true, если другое поле, проходящее валидацию, равно указанному значению. Это полезно для проверки согласия с "Условиями обслуживания" или подобными полями.

active_url

Поле, проходящее валидацию, должно иметь действительную запись A или AAAA согласно функции dns_get_record PHP. Имя хоста предоставленного URL извлекается с использованием функции parse_url PHP перед передачей в dns_get_record.

after:date

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

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

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

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

after_or_equal:date

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

alpha

Поле, проходящее валидацию, должно состоять исключительно из символов Unicode-алфавита, содержащихся в \p{L} и \p{M}.

Чтобы ограничить это правило валидации символами в диапазоне ASCII (a-z и A-Z), вы можете указать опцию ascii в правиле валидации:

'username' => 'alpha:ascii',

alpha_dash

Поле, подлежащее валидации, должно состоять исключительно из символов Unicode, альфа-цифровых символов, содержащихся в \p{L}, \p{M}, \p{N}, а также английских тире (-) и подчеркиваний (_).

Чтобы ограничить это правило валидации символами в диапазоне ASCII (a-z и A-Z), вы можете указать опцию ascii в правиле валидации:

'username' => 'alpha_dash:ascii',

alpha_num

Поле, подлежащее валидации, должно состоять исключительно из символов Unicode, альфа-цифровых символов, содержащихся в \p{L}, \p{M}, и \p{N}.

Чтобы ограничить это правило валидации символами в диапазоне ASCII (a-z и A-Z), вы можете указать опцию ascii в правиле валидации:

'username' => 'alpha_num:ascii',

array

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

Когда к правилу array предоставляются дополнительные значения, каждый ключ ввода должен присутствовать в списке значений, предоставленных правилу. В следующем примере ключ admin во входном массиве недопустим, так как его нет в списке значений, предоставленном правилу array:

use Illuminate\Support\Facades\Validator;
 
$input = [
'user' => [
'name' => 'Taylor Otwell',
'username' => 'taylorotwell',
'admin' => true,
],
];
 
Validator::make($input, [
'user' => 'array:name,username',
]);

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

ascii

Поле, подлежащее валидации, должно состоять исключительно из 7-битных ASCII-символов.

bail

Прекратите выполнение правил валидации для поля после первого нарушения правила.

В то время как правило bail прекращает валидацию конкретного поля, когда оно сталкивается с нарушением правила, метод stopOnFirstFailure информирует валидатор о том, что он должен прекратить валидацию всех атрибутов после первого нарушения правила:

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

before:date

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

before_or_equal:date

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

between:min,max

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

boolean

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

confirmed

Поле, подлежащее валидации, должно иметь соответствующее поле {field}_confirmation. Например, если поле, подлежащее валидации, - это password, соответствующее поле password_confirmation должно присутствовать во входных данных.

current_password

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

'password' => 'current_password:api'

date

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

date_equals:date

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

date_format:format,...

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

decimal:min,max

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

// Должно иметь ровно два знака после запятой (9.99)...
'price' => 'decimal:2'
 
// Должно иметь от 2 до 4 знаков после запятой...
'price' => 'decimal:2,4'

declined

Поле, подлежащее валидации, должно быть \"no\", \"off\", 0 или false.

declined_if:anotherfield,value,...

Поле, подлежащее валидации, должно быть \"no\", \"off\", 0 или false, если другое поле, подлежащее валидации, равно заданному значению.

different:field

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

digits:value

Целое число, подлежащее валидации, должно иметь точную длину значения.

digits_between:min,max

Целочисленная валидация должна иметь длину между заданными 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\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($data, [
'avatar' => [
'required',
Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
],
]);

distinct

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

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

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

'foo.*.id' => 'distinct:strict'

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

'foo.*.id' => 'distinct:ignore_case'

doesnt_start_with:foo,bar,...

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

doesnt_end_with:foo,bar,...

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

email

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

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

В приведенном выше примере применяются валидации RFCValidation и DNSCheckValidation. Вот полный список стилей валидации, которые вы можете применить:

  • rfc: RFCValidation
  • strict: NoRFCWarningsValidation
  • dns: DNSCheckValidation
  • spoof: SpoofCheckValidation
  • filter: FilterEmailValidation
  • filter_unicode: FilterEmailValidation::unicode()

Валидатор filter, который использует функцию filter_var PHP, поставляется с Laravel и был поведением валидации адреса электронной почты по умолчанию до версии Laravel 5.8.

Внимание Валидаторы dns и spoof требуют расширения PHP intl.

ends_with:foo,bar,...

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

enum

Правило Enum - это правило, основанное на классе, которое проверяет, содержит ли поле, подлежащее валидации, допустимое значение перечисления. Правило Enum принимает имя перечисления в качестве единственного аргумента конструктора:

use App\Enums\ServerStatus;
use Illuminate\Validation\Rule;
 
$request->validate([
'status' => [Rule::enum(ServerStatus::class)],
]);

exclude

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

exclude_if:anotherfield,value

Поле, подлежащее валидации, будет исключено из данных запроса, возвращаемых методами validate и validated, если поле anotherfield равно значению value.

Если требуется сложная условная логика исключения, вы можете использовать метод Rule::excludeIf. Этот метод принимает логическое значение или замыкание. Если передано замыкание, оно должно возвращать true или false для указания того, следует ли исключить поле, подлежащее валидации:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($request->all(), [
'role_id' => Rule::excludeIf($request->user()->is_admin),
]);
 
Validator::make($request->all(), [
'role_id' => Rule::excludeIf(fn () => $request->user()->is_admin),
]);

exclude_unless:anotherfield,value

Поле, подлежащее валидации, будет исключено из данных запроса, возвращаемых методами validate и validated, если поле anotherfield не равно значению value. Если value равно null (exclude_unless:name,null), поле, подлежащее валидации, будет исключено, если сравниваемое поле равно null или сравниваемое поле отсутствует в данных запроса.

exclude_with:anotherfield

Поле, подлежащее валидации, будет исключено из данных запроса, возвращаемых методами validate и validated, если поле anotherfield присутствует.

exclude_without:anotherfield

Поле, подлежащее валидации, будет исключено из данных запроса, возвращаемых методами validate и validated, если поле anotherfield отсутствует.

exists:table,column

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

Основное использование правила Exists

'state' => 'exists:states'

Если опция column не указана, будет использовано имя поля. Таким образом, в этом случае правило будет проверять, что таблица базы данных states содержит запись с значением столбца state, соответствующим значению атрибута state запроса.

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

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

'state' => 'exists:states,abbreviation'

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

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

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

'user_id' => 'exists:App\Models\User,id'

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

use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($data, [
'email' => [
'required',
Rule::exists('staff')->where(function (Builder $query) {
return $query->where('account_id', 1);
}),
],
]);

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

'state' => Rule::exists('states', 'abbreviation'),

file

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

filled

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

gt:field

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

gte:field

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

image

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

in:foo,bar,...

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

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($data, [
'zones' => [
'required',
Rule::in(['first-zone', 'second-zone']),
],
]);

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

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
$input = [
'airports' => ['NYC', 'LAS'],
];
 
Validator::make($input, [
'airports' => [
'required',
'array',
],
'airports.*' => Rule::in(['NYC', 'LIT']),
]);

in_array:anotherfield.*

Поле, подлежащее валидации, должно существовать в значениях поля anotherfield.

integer

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

Внимание Это правило валидации не проверяет, является ли входной параметр переменной типа "integer", а только лишь то, что входной параметр принимается PHP в правиле FILTER_VALIDATE_INT. Если вам нужно валидировать входные данные как число, используйте это правило в сочетании с правилом валидации numeric.

ip

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

ipv4

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

ipv6

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

json

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

lt:field

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

lte:field

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

lowercase

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

mac_address

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

max:value

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

max_digits:value

Целое число, подлежащее валидации, должно иметь максимальную длину value.

mimetypes:text/plain,...

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

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

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

mimes:foo,bar,...

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

Basic Usage Of MIME Rule

'photo' => 'mimes:jpg,bmp,png'

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

https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types

min:value

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

min_digits:value

Целое число, подлежащее валидации, должно иметь минимальную длину value.

multiple_of:value

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

missing

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

missing_if:anotherfield,value,...

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

missing_unless:anotherfield,value

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

missing_with:foo,bar,...

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

missing_with_all:foo,bar,...

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

not_in:foo,bar,...

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

use Illuminate\Validation\Rule;
 
Validator::make($data, [
'toppings' => [
'required',
Rule::notIn(['sprinkles', 'cherries']),
],
]);

not_regex:pattern

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

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

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

nullable

Поле, подлежащее валидации, может быть null.

numeric

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

password

Поле, подлежащее валидации, должно соответствовать паролю аутентифицированного пользователя.

Внимание Это правило было переименовано в current_password с намерением удалить его в Laravel 9. Пожалуйста, используйте правило Current Password вместо него.

present

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

prohibited

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

  • Значение равно null.
  • Значение - это пустая строка.
  • Значение - это пустой массив или пустой объект Countable.
  • Значение - это загруженный файл с пустым путем.

prohibited_if:anotherfield,value,...

Поле, подлежащее валидации, должно отсутствовать или быть пустым, если поле anotherfield равно любому значению value. Поле считается "пустым", если оно соответствует одному из следующих критериев:

  • Значение равно null.
  • Значение - это пустая строка.
  • Значение - это пустой массив или пустой объект Countable.
  • Значение - это загруженный файл с пустым путем.

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

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($request->all(), [
'role_id' => Rule::prohibitedIf($request->user()->is_admin),
]);
 
Validator::make($request->all(), [
'role_id' => Rule::prohibitedIf(fn () => $request->user()->is_admin),
]);

prohibited_unless:anotherfield,value,...

Поле, подлежащее валидации, должно отсутствовать или быть пустым, если поле anotherfield не равно любому значению value. Поле считается "пустым", если оно соответствует одному из следующих критериев:

  • Значение равно null.
  • Значение - это пустая строка.
  • Значение - это пустой массив или пустой объект Countable.
  • Значение - это загруженный файл с пустым путем.

prohibits:anotherfield,...

Если поле, подлежащее валидации, не отсутствует или не является пустым, все поля в anotherfield должны отсутствовать или быть пустыми. Поле считается "пустым", если оно соответствует одному из следующих критериев:

  • Значение равно null.
  • Значение - это пустая строка.
  • Значение - это пустой массив или пустой объект Countable.
  • Значение - это загруженный файл с пустым путем.

regex:pattern

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

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

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

required

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

  • Значение равно null.
  • Значение - это пустая строка.
  • Значение - это пустой массив или пустой объект Countable.
  • Значение - это загруженный файл без пути.

required_if:anotherfield,value,...

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

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

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($request->all(), [
'role_id' => Rule::requiredIf($request->user()->is_admin),
]);
 
Validator::make($request->all(), [
'role_id' => Rule::requiredIf(fn () => $request->user()->is_admin),
]);

required_if_accepted:_anotherfield,...

Поле, подлежащее валидации, должно присутствовать и не быть пустым, если поле anotherfield равно yes, on, 1, \"1\", true или \"true\".

required_unless:anotherfield,value,...

Поле, подлежащее валидации, должно присутствовать и не быть пустым, если поле anotherfield не равно любому значению value. Это также означает, что anotherfield должно присутствовать в данных запроса, если value равно null. Если value равно null (required_unless:name,null), поле, подлежащее валидации, будет обязательным, если сравниваемое поле равно null или сравниваемое поле отсутствует в данных запроса.

required_with:foo,bar,...

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

required_with_all:foo,bar,...

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

required_without:foo,bar,...

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

required_without_all:foo,bar,...

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

required_array_keys:foo,bar,...

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

same:field

Указанное поле field должно соответствовать полю, подлежащему валидации.

size:value

Поле, подлежащее валидации, должно иметь размер, соответствующий указанному value. Для строковых данных value соответствует количеству символов. Для числовых данных value соответствует заданному целочисленному значению (атрибут также должен иметь правило numeric или integer). Для массива size соответствует count массива. Для файлов size соответствует размер файла в килобайтах. Рассмотрим несколько примеров:

// Проверить, что строка состоит ровно из 12 символов...
'title' => 'size:12';
 
// Проверить, что предоставленное целое число равно 10...
'seats' => 'integer|size:10';
 
// Проверить, что массив состоит ровно из 5 элементов...
'tags' => 'array|size:5';
 
// Проверить, что загруженный файл составляет ровно 512 килобайт...
'image' => 'file|size:512';

starts_with:foo,bar,...

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

string

Поле, подлежащее валидации, должно быть строкой. Если вы хотите разрешить поле также быть null, вы должны присвоить полю правило nullable.

timezone

Поле, подлежащее валидации, должно быть допустимым идентификатором часового пояса согласно методу DateTimeZone::listIdentifiers.

Аргументы принимаемые методом DateTimeZone::listIdentifiers также могут быть предоставлены для этого правила валидации:

'timezone' => 'required|timezone:all';
 
'timezone' => 'required|timezone:Africa';
 
'timezone' => 'required|timezone:per_country,US';

unique:table,column

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

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

Вместо прямого указания имени таблицы вы можете указать Eloquent-модель, которая должна использоваться для определения имени таблицы:

'email' => 'unique:App\Models\User,email_address'

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

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

Указание пользовательского подключения к базе данных

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

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

Принудительное игнорирование уникального правила для указанного ID:

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

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

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);

Внимание Никогда не передавайте управляемые пользователем входные данные запроса в метод ignore. Вместо этого передавайте только системно сгенерированный уникальный идентификатор, такой как автоинкрементный идентификатор или UUID от экземпляра модели Eloquent. В противном случае ваше приложение будет уязвимо для атаки SQL-инъекцией.

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

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

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

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

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

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

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

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

'email' => Rule::unique('users')->where(fn (Builder $query) => $query->where('account_id', 1))

uppercase

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

url

Поле, подлежащее валидации, должно быть действительным URL.

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

'url' => 'url:http,https',
 
'game' => 'url:minecraft,steam',

ulid

Поле, подлежащее валидации, должно быть действительным уникальным лексикографически упорядоченным идентификатором (ULID).

uuid

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

Условное добавление правил

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

Иногда вам может потребоваться не проверять определенное поле, если у другого поля есть заданное значение. Вы можете сделать это, используя правило валидации exclude_if. В этом примере поля appointment_date и doctor_name не будут проверяться, если поле has_appointment имеет значение false:

use Illuminate\Support\Facades\Validator;
 
$validator = Validator::make($data, [
'has_appointment' => 'required|boolean',
'appointment_date' => 'exclude_if:has_appointment,false|required|date',
'doctor_name' => 'exclude_if:has_appointment,false|required|string',
]);

Кроме того, вы можете использовать правило exclude_unless для того, чтобы не проверять определенное поле, если другое поле не имеет заданное значение:

$validator = Validator::make($data, [
'has_appointment' => 'required|boolean',
'appointment_date' => 'exclude_unless:has_appointment,true|required|date',
'doctor_name' => 'exclude_unless:has_appointment,true|required|string',
]);

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

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

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

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

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

Сложная условная валидация

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

use Illuminate\Support\Facades\Validator;
 
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'games' => 'required|numeric',
]);

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

use Illuminate\Support\Fluent;
 
$validator->sometimes('reason', 'required|max:500', function (Fluent $input) {
return $input->games >= 100;
});

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

$validator->sometimes(['reason', 'cost'], 'required', function (Fluent $input) {
return $input->games >= 100;
});

Примечание Параметр $input, переданный в ваше замыкание, будет экземпляром Illuminate\Support\Fluent и может использоваться для доступа к вашему вводу и файлам, подлежащим валидации.

Сложная условная валидация массива

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

$input = [
'channels' => [
[
'type' => 'email',
'address' => '[email protected]',
],
[
'type' => 'url',
'address' => 'https://example.com',
],
],
];
 
$validator->sometimes('channels.*.address', 'email', function (Fluent $input, Fluent $item) {
return $item->type === 'email';
});
 
$validator->sometimes('channels.*.address', 'url', function (Fluent $input, Fluent $item) {
return $item->type !== 'email';
});

Как и параметр $input, переданный в замыкание, параметр $item является экземпляром Illuminate\Support\Fluent, когда данные атрибута представляют собой массив; в противном случае это строка.

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

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

use Illuminate\Support\Facades\Validator;
 
$input = [
'user' => [
'name' => 'Taylor Otwell',
'username' => 'taylorotwell',
'admin' => true,
],
];
 
Validator::make($input, [
'user' => 'array:name,username',
]);

В целом, вы всегда должны указывать ключи массива, которые могут присутствовать в вашем массиве. В противном случае методы validate и validated валидатора будут возвращать все проверенные данные, включая массив и все его ключи, даже если эти ключи не были проверены другими вложенными правилами валидации массива.

Валидация вложенных массивов

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

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

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

$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 email address',
]
],

Доступ к вложенным данным массива

Иногда вам может потребоваться получить доступ к значению для данного элемента вложенного массива при присвоении правил валидации атрибуту. Это можно сделать с помощью метода Rule::forEach. Метод forEach принимает замыкание, которое будет вызвано для каждой итерации массива-атрибута, подлежащего валидации, и получит значение атрибута и явное, полностью раскрытое имя атрибута. Замыкание должно вернуть массив правил, которые следует присвоить элементу массива:

use App\Rules\HasPermission;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
$validator = Validator::make($request->all(), [
'companies.*.id' => Rule::forEach(function (string|null $value, string $attribute) {
return [
Rule::exists(Company::class, 'id'),
new HasPermission('manage-company', $value),
];
}),
]);

Индексы и позиции сообщений об ошибках

При валидации массивов может потребоваться ссылаться на индекс или позицию конкретного элемента, который не прошел валидацию, в сообщении об ошибке, отображаемом вашим приложением. Для этого вы можете включить заполнители :index (начиная с 0) и :position (начиная с 1) в вашем пользовательском сообщении о валидации:

use Illuminate\Support\Facades\Validator;
 
$input = [
'photos' => [
[
'name' => 'BeachVacation.jpg',
'description' => 'A photo of my beach vacation!',
],
[
'name' => 'GrandCanyon.jpg',
'description' => '',
],
],
];
 
Validator::validate($input, [
'photos.*.description' => 'required',
], [
'photos.*.description.required' => 'Please describe photo #:position.',
]);

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

При необходимости вы можете ссылаться на более глубоко вложенные индексы и позиции с использованием second-index, second-position, third-index, third-position и так далее.

'photos.*.attributes.*.string' => 'Invalid attribute for photo #:second-position.',

Валидация файлов

Laravel предоставляет различные правила валидации, которые можно использовать для проверки загруженных файлов, такие как mimes, image, min и max. Хотя вы свободны указывать эти правила индивидуально при валидации файлов, Laravel также предлагает удобный строитель правил валидации файлов, который может оказаться удобным:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;
 
Validator::validate($input, [
'attachment' => [
'required',
File::types(['mp3', 'wav'])
->min(1024)
->max(12 * 1024),
],
]);

Если ваше приложение принимает изображения, загружаемые вашими пользователями, вы можете использовать метод image конструктора правила File для указания того, что загруженный файл должен быть изображением. Кроме того, правило dimensions может использоваться для ограничения размеров изображения:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;
 
Validator::validate($input, [
'photo' => [
'required',
File::image()
->min(1024)
->max(12 * 1024)
->dimensions(Rule::dimensions()->maxWidth(1000)->maxHeight(500)),
],
]);

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

Размеры файлов

Для удобства минимальный и максимальный размеры файла могут быть указаны как строка с суффиксом, указывающим единицы размера файла. Поддерживаются суффиксы kb, mb, gb и tb:

File::image()
->min('1kb')
->max('10mb')

Типы файлов

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

https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types

Валидация паролей

Для обеспечения того, чтобы пароли имели достаточный уровень сложности, вы можете использовать объект правила Password Laravel:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\Password;
 
$validator = Validator::make($request->all(), [
'password' => ['required', 'confirmed', Password::min(8)],
]);

Объект правила Password позволяет легко настраивать требования к сложности пароля для вашего приложения, такие как указание, что пароли должны содержать как минимум одну букву, цифру, символ или символы с разным регистром:

// Требуется не менее 8 символов...
Password::min(8)
 
// Требуется хотя бы одна буква...
Password::min(8)->letters()
 
// Требуется хотя бы одна прописная и одна строчная буква...
Password::min(8)->mixedCase()
 
// Требуется хотя бы одна цифра...
Password::min(8)->numbers()
 
// Требуется хотя бы один символ...
Password::min(8)->symbols()

Кроме того, вы можете убедиться, что пароль не был скомпрометирован в утечке публичных данных о паролях, используя метод uncompromised:

Password::min(8)->uncompromised()

Внутренне объект правила Password использует модель k-анонимности, чтобы определить, был ли пароль утекший через службу haveibeenpwned.com, не нарушая конфиденциальность или безопасность пользователя.

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

// Убедитесь, что пароль не появляется более 3 раз в одном утечке данных...
Password::min(8)->uncompromised(3);

Конечно, вы можете объединить все методы в приведенных выше примерах:

Password::min(8)
->letters()
->mixedCase()
->numbers()
->symbols()
->uncompromised()

Определение правил пароля по умолчанию

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

use Illuminate\Validation\Rules\Password;
 
/**
* Инициализировать все службы приложения.
*/
public function boot(): void
{
Password::defaults(function () {
$rule = Password::min(8);
 
return $this->app->isProduction()
? $rule->mixedCase()->uncompromised()
: $rule;
});
}

Затем, когда вы захотите применить стандартные правила к конкретному паролю в процессе валидации, вы можете вызвать метод defaults без аргументов:

'password' => ['required', Password::defaults()],

Иногда вам может потребоваться добавить дополнительные правила валидации к вашим стандартным правилам валидации паролей. Вы можете использовать метод rules для этого:

use App\Rules\ZxcvbnRule;
 
Password::defaults(function () {
$rule = Password::min(8)->rules([new ZxcvbnRule]);
 
// ...
});

Пользовательские правила валидации

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

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

php artisan make:rule Uppercase

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

<?php
 
namespace App\Rules;
 
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
 
class Uppercase implements ValidationRule
{
/**
* Запустить правило валидации.
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (strtoupper($value) !== $value) {
$fail('The :attribute must be uppercase.');
}
}
}

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

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

Перевод сообщений валидации

Вместо предоставления конкретного сообщения об ошибке замыканию $fail, вы также можете предоставить ключ строки перевода и указать Laravel перевести сообщение об ошибке:

if (strtoupper($value) !== $value) {
$fail('validation.uppercase')->translate();
}

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

$fail('validation.location')->translate([
'value' => $this->value,
], 'fr')

Доступ к дополнительным данным

Если вашему классу пользовательского правила валидации необходим доступ ко всем остальным данным, проходящим валидацию, ваш класс правила может реализовывать интерфейс Illuminate\Contracts\Validation\DataAwareRule. Этот интерфейс требует, чтобы ваш класс определял метод setData. Этот метод будет автоматически вызываться Laravel (перед продолжением валидации) со всеми данными, проходящими валидацию:

<?php
 
namespace App\Rules;
 
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidationRule;
 
class Uppercase implements DataAwareRule, ValidationRule
{
/**
* Вся информация, подлежащая валидации.
*
* @var array<string, mixed>
*/
protected $data = [];
 
// ...
 
/**
* Установить данные, подлежащие валидации.
*
* @param array<string, mixed> $data
*/
public function setData(array $data): static
{
$this->data = $data;
 
return $this;
}
}

Или, если вашему классу правила валидации требуется доступ к экземпляру валидатора, выполняющего валидацию, вы можете реализовать интерфейс ValidatorAwareRule:

<?php
 
namespace App\Rules;
 
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Illuminate\Validation\Validator;
 
class Uppercase implements ValidationRule, ValidatorAwareRule
{
/**
* Экземпляр валидатора.
*
* @var \Illuminate\Validation\Validator
*/
protected $validator;
 
// ...
 
/**
* Установить текущий валидатор.
*/
public function setValidator(Validator $validator): static
{
$this->validator = $validator;
 
return $this;
}
}

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

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

use Illuminate\Support\Facades\Validator;
use Closure;
 
$validator = Validator::make($request->all(), [
'title' => [
'required',
'max:255',
function (string $attribute, mixed $value, Closure $fail) {
if ($value === 'foo') {
$fail("The {$attribute} is invalid.");
}
},
],
]);

Неявные правила

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

use Illuminate\Support\Facades\Validator;
 
$rules = ['name' => 'unique:users,name'];
 
$input = ['name' => ''];
 
Validator::make($input, $rules)->passes(); // true

Для выполнения пользовательского правила даже при пустом значении атрибута, правило должно подразумевать, что атрибут обязателен. Чтобы быстро создать новый объект неявного правила, вы можете использовать Artisan-команду make:rule с опцией --implicit:

php artisan make:rule Uppercase --implicit

Внимание Правило "implicit" лишь подразумевает, что атрибут обязателен. То, действительно ли оно считает отсутствующий или пустой атрибут недействительным, зависит от вас.