Валідація

Вступ

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',
]);

З іншого боку, якщо назва вашого поля містить буквальний період, ви можете явно запобігти його інтерпретації як синтаксису "dot", екрануючи період зворотним слешем:

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

Відображення помилок валідації

Отже, що робити, якщо поля вхідного запиту не проходять задані правила валідації? Як згадувалося раніше, Laravel автоматично перенаправить користувача назад до попереднього місця. Крім того, всі помилки валідації та вхідні дані запиту будуть автоматично збережені у сесії.

Змінна $errors ділиться з усіма представленнями вашого застосунку за допомогою middleware Illuminate\View\Middleware\ShareErrorsFromSession, яке надається групою middleware web. Коли це middleware застосовується, змінна $errors завжди буде доступна у ваших представленнях, що дозволяє зручно припускати, що змінна $errors завжди визначена і може бути безпечно використана. Змінна $errors буде екземпляром Illuminate\Support\MessageBag. Для отримання додаткової інформації про роботу з цим об'єктом, ознайомтеся з його документацією.

Отже, у нашому прикладі користувач буде перенаправлений до методу create нашого контролера, коли перевірка не вдасться, що дозволить нам відобразити повідомлення про помилки у представленні:

<!-- /resources/views/post/create.blade.php -->
 
<h1>Створити пост</h1>
 
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
 
<!-- Форма створення допису -->

Налаштування повідомлень про помилки

Правила валідації, вбудовані в Laravel, мають повідомлення про помилки, які знаходяться у файлі 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

Ви можете використовувати директиву @error Blade, щоб швидко визначити, чи існують повідомлення про помилки валідації для заданого атрибуту. У межах директиви @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 вашого застосунку. Через це, вам часто потрібно буде позначати ваші "необов'язкові" поля запиту як 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": "Назва команди має бути рядком. (і ще 4 помилки)",
"errors": {
"team_name": [
"Назва команди має бути рядком.",
"Назва команди має містити щонайменше 1 символ."
],
"authorization.role": [
"Вибране значення authorization.role недійсне."
],
"users.0.email": [
"Поле users.0.email є обов’язковим."
],
"users.2.email": [
"Поле users.2.email має містити дійсну електронну адресу."
]
}
}

Валідація Запитів Форми

Створення запитів форми

Для більш складних сценаріїв валідації, ви можете створити "запит форми". Запити форми - це користувацькі класи запитів, які інкапсулюють власну логіку валідації та авторизації. Щоб створити клас запиту форми, ви можете скористатися командою 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\ValidationRule|array<mixed>|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-представлення помилок валідації.

Потрібно додати перевірку запитів форми в реальному часі до вашого фронтенду на базі Inertia у Laravel? Ознайомтеся з 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',
'Щось не так із цим полем!'
);
}
}
];
}

Як зазначено, масив, що повертається методом 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 буде автоматично повернена, і метод вашого контролера не буде виконано.

Якщо ви плануєте обробляти логіку авторизації для запиту в іншій частині вашого застосунку, ви можете повністю видалити метод authorize або просто повернути true:

/**
* Визначити, чи авторизований користувач для виконання цього запиту.
*/
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, що містить помилки валідації, дозволяючи отримати повідомлення про помилки для конкретної форми. Щоб досягти цього, передайте ім'я як другий аргумент до withErrors:

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

Ви можете отримати доступ до іменованого екземпляра MessageBag з змінної $errors:

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

Налаштування Повідомлень про Помилки

Якщо потрібно, ви можете надати власні повідомлення про помилки, які екземпляр валідатора повинен використовувати замість стандартних повідомлень про помилки, наданих Laravel. Існує кілька способів вказати власні повідомлення. По-перше, ви можете передати власні повідомлення як третій аргумент методу Validator::make:

$validator = Validator::make($input, $rules, $messages = [
'required' => 'Поле :attribute обов'язкове.',
]);

У цьому прикладі заповнювач :attribute буде замінено на фактичну назву поля, яке перевіряється. Ви також можете використовувати інші заповнювачі в повідомленнях про валідацію. Наприклад:

$messages = [
'same' => ':attribute і :other мають збігатися.',
'size' => 'Поле :attribute має бути точно :size.',
'between' => 'Значення :attribute (:input) не входить у діапазон від :min до :max.',
'in' => 'Поле :attribute має бути одним із наступних типів: :values.',
];

Користувацьке повідомлення для заданого атрибуту

Іноді ви можете захотіти вказати власне повідомлення про помилку лише для конкретного атрибута. Ви можете зробити це, використовуючи нотацію "крапка". Спочатку вкажіть ім'я атрибута, а потім правило:

$messages = [
'email.required' => 'Нам потрібно знати вашу електронну адресу!',
];

Значення Користувацьких Атрибутів

Багато вбудованих повідомлень про помилки 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' => 'Нам потрібно знати вашу електронну адресу!',
'max' => 'Ваша електронна адреса надто довга!'
],
],

Зазначення Атрибутів у Мовних Файлах

Багато вбудованих повідомлень про помилки 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'
]);

Якщо це правило валідації не виконується, буде згенеровано таке повідомлення про помилку:

Поле номера кредитної картки є обов’язковим, якщо тип оплати — cc.

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

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

За замовчуванням, скелет застосунку Laravel не включає директорію lang. Якщо ви хочете налаштувати мовні файли Laravel, ви можете опублікувати їх за допомогою команди Artisan lang:publish.

Після визначення цього значення правило валідації видасть таке повідомлення про помилку:

Поле номера кредитної картки є обов’язковим, якщо тип оплати — кредитна картка.

Доступні правила валідації

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

Булеві значення

Рядки

Числові

Масиви

Дати

Файли

База даних

Утиліти

accepted

Поле, що перевіряється, має бути "yes", "on", 1, "1", true або "true". Це корисно для перевірки прийняття "Умов обслуговування" або подібних полів.

accepted_if:anotherfield,value,...

Поле, що перевіряється, має бути "yes", "on", 1, "1", true або "true", якщо інше поле, що перевіряється, дорівнює вказаному значенню. Це корисно для перевірки прийняття "Умов обслуговування" або подібних полів.

active_url

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

after:date

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

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

Замість передачі рядка дати для оцінки за допомогою strtotime, ви можете вказати інше поле для порівняння з датою:

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

Для зручності правила на основі дат можуть бути створені за допомогою гнучкого конструктора правил date:

use Illuminate\Validation\Rule;
 
'start_date' => [
    'required',
    Rule::date()->after(today()->addDays(7)),
],

Методи afterToday та todayOrAfter можуть бути використані для чіткого вираження, що дата має бути після сьогоднішнього дня або сьогодні чи пізніше, відповідно:

'start_date' => [
    'required',
    Rule::date()->afterToday(),
],

after_or_equal:date

Поле, що перевіряється, повинно бути значенням після або рівним вказаній даті. Для отримання додаткової інформації дивіться правило after.

Для зручності правила на основі дат можуть бути створені за допомогою гнучкого конструктора правил date:

use Illuminate\Validation\Rule;
 
'start_date' => [
    'required',
    Rule::date()->afterOrEqual(today()->addDays(7)),
],

anyOf

Правило валідації Rule::anyOf дозволяє вказати, що поле, яке перевіряється, повинно задовольняти будь-який з наданих наборів правил валідації. Наприклад, наступне правило перевірить, що поле username є або адресою електронної пошти, або алфавітно-цифровим рядком (включаючи тире), який має щонайменше 6 символів:

use Illuminate\Validation\Rule;
 
'username' => [
    'required',
    Rule::anyOf([
        ['string', 'email'],
        ['string', 'alpha_dash', 'min:6'],
    ]),
],

alpha

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

Щоб обмежити це правило валідації символами в діапазоні ASCII (a-z та A-Z), ви можете надати опцію ascii до правила валідації:

'username' => 'alpha:ascii',

alpha_dash

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

Щоб обмежити це правило валідації символами в діапазоні ASCII (a-z, A-Z і 0-9), ви можете надати опцію ascii до правила валідації:

'username' => 'alpha_dash:ascii',

alpha_num

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

Щоб обмежити це правило валідації символами в діапазоні ASCII (a-z, A-Z і 0-9), ви можете надати опцію ascii до правила валідації:

'username' => 'alpha_num:ascii',

array

Поле, що перевіряється, має бути PHP array.

Коли додаткові значення надаються правилу 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.

Для зручності правила на основі дат також можуть бути створені за допомогою гнучкого конструктора правил date:

use Illuminate\Validation\Rule;
 
'start_date' => [
    'required',
    Rule::date()->before(today()->subDays(7)),
],

Методи beforeToday та todayOrBefore можуть бути використані для вираження вимоги, що дата має бути до сьогодні або сьогодні чи раніше, відповідно:

'start_date' => [
    'required',
    Rule::date()->beforeToday(),
],

before_or_equal:date

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

Для зручності, правила на основі дат також можуть бути створені за допомогою гнучкого конструктора правил date:

use Illuminate\Validation\Rule;
 
'start_date' => [
    'required',
    Rule::date()->beforeOrEqual(today()->subDays(7)),
],

between:min,max

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

boolean

Поле, що перевіряється, повинно мати можливість бути приведеним до булевого типу. Прийнятні значення: true, false, 1, 0, "1" та "0".

confirmed

Поле, що перевіряється, повинно мати відповідне поле {field}_confirmation. Наприклад, якщо поле, що перевіряється, є password, відповідне поле password_confirmation повинно бути присутнім у введених даних.

Ви також можете передати власне ім'я поля підтвердження. Наприклад, confirmed:repeat_username очікуватиме, що поле repeat_username відповідатиме полю, яке перевіряється.

contains:foo,bar,...

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

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($data, [
    'roles' => [
        'required',
        'array',
        Rule::contains(['admin', 'editor']),
    ],
]);

current_password

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

'password' => 'current_password:api'

date

Поле, яке перевіряється, має бути дійсною, не відносною датою згідно з функцією PHP strtotime.

date_equals:date

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

date_format:format,...

Поле, що перевіряється, повинно відповідати одному з вказаних форматів. Ви повинні використовувати або date, або date_format при перевірці поля, але не обидва. Це правило валідації підтримує всі формати, які підтримуються класом PHP DateTime.

Для зручності правила на основі дат можуть бути створені за допомогою гнучкого конструктора правил date:

use Illuminate\Validation\Rule;
 
'start_date' => [
    'required',
    Rule::date()->format('Y-m-d'),
],

decimal:min,max

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

// Має містити рівно два десяткових знаки (9.99)...
'price' => 'decimal:2'
 
// Має містити від 2 до 4 знаків після коми...
'price' => 'decimal:2,4'

declined

Поле, що перевіряється, має бути "no", "off", 0, "0", false або "false".

declined_if:anotherfield,value,...

Поле, що перевіряється, має бути "no", "off", 0, "0", false або "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.

Обмеження співвідношення повинно бути представлене як ширина, поділена на висоту. Це можна вказати або дробом, як 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 - Перевірте адресу електронної пошти відповідно до підтримуваних RFC.
  • strict: NoRFCWarningsValidation - Перевіряє електронну пошту відповідно до підтримуваних RFC, не проходячи перевірку, якщо знайдено попередження (наприклад, кінцеві крапки та кілька послідовних крапок).
  • dns: DNSCheckValidation - Переконайтеся, що домен адреси електронної пошти має дійсний MX-запис.
  • spoof: SpoofCheckValidation - Переконайтеся, що адреса електронної пошти не містить омографів або оманливих символів Unicode.
  • filter: FilterEmailValidation - Переконайтеся, що адреса електронної пошти є дійсною відповідно до функції PHP filter_var.
  • filter_unicode: FilterEmailValidation::unicode() - Переконайтеся, що адреса електронної пошти є дійсною відповідно до функції PHP filter_var, дозволяючи деякі символи Unicode.

Для зручності правила валідації електронної пошти можуть бути створені за допомогою гнучкого конструктора правил:

use Illuminate\Validation\Rule;
 
$request->validate([
    'email' => [
        'required',
        Rule::email()
            ->rfcCompliant(strict: false)
            ->validateMxRecord()
            ->preventSpoofing()
    ],
]);

Валідатори dns та spoof вимагають розширення PHP intl.

ends_with:foo,bar,...

Поле, що перевіряється, має закінчуватися одним із вказаних значень.

enum

Правило Enum - це правило на основі класу, яке перевіряє, чи містить поле, що перевіряється, дійсне значення enum. Правило Enum приймає назву enum як єдиний аргумент конструктора. При перевірці примітивних значень, для правила Enum слід надати підтримуваний Enum:

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

Методи only та except правила Enum можуть бути використані для обмеження, які випадки перерахування слід вважати дійсними:

Rule::enum(ServerStatus::class)
    ->only([ServerStatus::Pending, ServerStatus::Active]);
 
Rule::enum(ServerStatus::class)
    ->except([ServerStatus::Pending, ServerStatus::Active]);

Метод when може бути використаний для умовної модифікації правила Enum:

use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
 
Rule::enum(ServerStatus::class)
    ->when(
        Auth::user()->isAdmin(),
        fn ($rule) => $rule->only(...),
        fn ($rule) => $rule->only(...),
    );

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) {
            $query->where('account_id', 1);
        }),
    ],
]);

Ви можете явно вказати ім'я стовпця бази даних, яке має бути використане правилом exists, згенерованим методом Rule::exists, надавши ім'я стовпця як другий аргумент методу exists:

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

Іноді ви можете захотіти перевірити, чи існує масив значень у базі даних. Ви можете зробити це, додавши обидва правила exists та array до поля, яке перевіряється:

'states' => ['array', Rule::exists('states', 'abbreviation')],

Коли обидва ці правила призначені для поля, Laravel автоматично створить єдиний запит, щоб визначити, чи всі задані значення існують у вказаній таблиці.

extensions:foo,bar,...

Файл, що перевіряється, повинен мати призначене користувачем розширення, яке відповідає одному з перелічених розширень:

'photo' => ['required', 'extensions:jpg,png'],

Ви ніколи не повинні покладатися на перевірку файлу лише за його розширенням, призначеним користувачем. Це правило зазвичай завжди слід використовувати в поєднанні з правилами mimes або mimetypes.

file

Поле, що перевіряється, має бути успішно завантаженим файлом.

filled

Поле, що перевіряється, не повинно бути порожнім, коли воно присутнє.

gt:field

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

gte:field

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

hex_color

Поле, що перевіряється, повинно містити дійсне значення кольору у форматі шістнадцяткового коду.

image

Файл, що перевіряється, повинен бути зображенням (jpg, jpeg, png, bmp, gif або webp).

За замовчуванням правило зображення не дозволяє файли SVG через можливість вразливостей XSS. Якщо вам потрібно дозволити файли SVG, ви можете надати директиву allow_svg до правила image (image:allow_svg).

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.

in_array_keys:value.*

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

'config' => 'array|in_array_keys:timezone'

integer

Поле, що перевіряється, має бути цілим числом.

Це правило валідації не перевіряє, чи є вхідні дані змінного типу "integer", лише те, що вхідні дані є типом, прийнятним правилом PHP FILTER_VALIDATE_INT. Якщо вам потрібно перевірити вхідні дані як число, будь ласка, використовуйте це правило в поєднанні з правилом валідації numeric.

ip

Поле, що перевіряється, має бути IP-адресою.

ipv4

Поле, що перевіряється, має бути IPv4-адресою.

ipv6

Поле, що перевіряється, має бути IPv6-адресою.

json

Поле, що перевіряється, має бути дійсним JSON рядком.

lt:field

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

lte:field

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

lowercase

Поле, що перевіряється, має бути в нижньому регістрі.

list

Поле, що перевіряється, має бути масивом, який є списком. Масив вважається списком, якщо його ключі складаються з послідовних чисел від 0 до count($array) - 1.

mac_address

Поле, що перевіряється, має бути MAC-адресою.

max:value

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

max_digits:value

Ціле число, що перевіряється, повинно мати максимальну довжину значення.

mimetypes:text/plain,...

Файл, що перевіряється, повинен відповідати одному з вказаних MIME-типів:

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

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

mimes:foo,bar,...

Файл, що перевіряється, повинен мати MIME-тип, що відповідає одному з перелічених розширень:

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

Хоча вам потрібно вказати лише розширення, це правило фактично перевіряє MIME-тип файлу, читаючи вміст файлу та визначаючи його MIME-тип. Повний список MIME-типів та їх відповідних розширень можна знайти за наступним посиланням:

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

Типи MIME та Розширення

Це правило валідації не перевіряє відповідність між типом MIME та розширенням, яке користувач призначив файлу. Наприклад, правило валідації mimes:png вважатиме файл, що містить дійсний вміст PNG, дійсним зображенням PNG, навіть якщо файл названо photo.txt. Якщо ви хочете перевірити розширення файлу, призначене користувачем, ви можете використовувати правило extensions.

min:value

Поле, яке перевіряється, повинно мати мінімальне значення. Рядки, числові значення, масиви та файли оцінюються так само, як і правило розміру.

min_digits:value

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

multiple_of: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

Поле, що перевіряється, не повинно відповідати заданому регулярному виразу.

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

Коли використовуєте шаблони regex / not_regex, може бути необхідно вказати ваші правила валідації, використовуючи масив замість роздільників |, особливо якщо регулярний вираз містить символ |.

nullable

Поле, що перевіряється, може бути null.

numeric

Поле, що перевіряється, має бути числовим.

present

Поле, що перевіряється, повинно існувати у вхідних даних.

present_if:anotherfield,value,...

Поле, що перевіряється, має бути присутнім, якщо поле anotherfield дорівнює будь-якому value.

present_unless:anotherfield,value

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

present_with:foo,bar,...

Поле, що перевіряється, повинно бути присутнім лише якщо будь-яке з інших зазначених полів присутнє.

present_with_all:foo,bar,...

Поле, що перевіряється, повинно бути присутнім лише якщо всі інші вказані поля присутні.

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_if_accepted:anotherfield,...

Поле, яке перевіряється, повинно бути відсутнім або порожнім, якщо поле anotherfield дорівнює "yes", "on", 1, "1", true або "true".

prohibited_if_declined:anotherfield,...

Поле, яке перевіряється, має бути відсутнім або порожнім, якщо поле anotherfield дорівнює "no", "off", 0, "0", false або "false".

prohibited_unless:anotherfield,value,...

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

  • Значення є null.
  • Значення є порожнім рядком.
  • Значення є порожнім масивом або порожнім об'єктом Countable.
  • Значення є завантаженим файлом з порожнім шляхом.

prohibits:anotherfield,...

Якщо поле, яке перевіряється, не відсутнє або не порожнє, всі поля в anotherfield повинні бути відсутніми або порожніми. Поле є "порожнім", якщо воно відповідає одному з наступних критеріїв:

  • Значення є null.
  • Значення є порожнім рядком.
  • Значення є порожнім масивом або порожнім об'єктом Countable.
  • Значення є завантаженим файлом з порожнім шляхом.

regex:pattern

Поле, що перевіряється, повинно відповідати заданому регулярному виразу.

Внутрішньо це правило використовує PHP-функцію preg_match. Вказаний шаблон повинен відповідати тому ж форматуванню, яке вимагається 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_if_declined:anotherfield,...

Поле, яке перевіряється, має бути присутнім і не порожнім, якщо поле anotherfield дорівнює "no", "off", 0, "0", false або "false".

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

Дане поле повинно відповідати полю, яке перевіряється.

size:value

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

// Перевірте, що рядок має рівно 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 для правила унікальності:

Іноді ви можете захотіти ігнорувати певний ID під час унікальної валідації. Наприклад, розгляньте екран "оновлення профілю", який включає ім'я користувача, адресу електронної пошти та місцезнаходження. Ви, ймовірно, захочете перевірити, що адреса електронної пошти є унікальною. Однак, якщо користувач змінює лише поле імені, а не поле електронної пошти, ви не хочете, щоб виникла помилка валідації, оскільки користувач вже є власником вказаної адреси електронної пошти.

Щоб вказати валідатору ігнорувати ID користувача, ми використаємо клас Rule для плавного визначення правила. У цьому прикладі ми також вкажемо правила валідації як масив замість використання символу | для розділення правил:

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

Ви ніколи не повинні передавати будь-які дані запиту, контрольовані користувачем, у метод ignore. Натомість слід передавати лише системно згенерований унікальний ідентифікатор, такий як автоінкрементний ID або 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))

Ігнорування м'яко видалених записів у перевірках унікальності:

За замовчуванням правило unique включає м'яко видалені записи при визначенні унікальності. Щоб виключити м'яко видалені записи з перевірки унікальності, ви можете викликати метод withoutTrashed:

Rule::unique('users')->withoutTrashed();

Якщо ваша модель використовує іншу назву стовпця, ніж deleted_at, для м'яко видалених записів, ви можете вказати назву стовпця при виклику методу withoutTrashed:

Rule::unique('users')->withoutTrashed('was_deleted_at');

uppercase

Поле, що перевіряється, має бути у верхньому регістрі.

url

Поле, що перевіряється, має бути дійсною URL-адресою.

Якщо ви хочете вказати протоколи URL, які слід вважати дійсними, ви можете передати протоколи як параметри правила валідації:

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

ulid

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

uuid

Поле, яке перевіряється, має бути дійсним універсально унікальним ідентифікатором (UUID) RFC 9562 (версія 1, 3, 4, 5, 6, 7 або 8).

Ви також можете перевірити, чи відповідає даний UUID специфікації UUID за версією:

'uuid' => 'uuid:4'

Умовне Додавання Правил

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

Ви можете іноді бажати не перевіряти певне поле, якщо інше поле має певне значення. Ви можете досягти цього, використовуючи правило валідації 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 до вашого списку правил:

$validator = 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|integer|min:0',
]);

Давайте припустимо, що наш веб-застосунок призначений для колекціонерів ігор. Якщо колекціонер ігор реєструється в нашому застосунку і володіє більше ніж 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, переданий у ваш closure, буде екземпляром Illuminate\Support\Fluent і може бути використаний для доступу до ваших вхідних даних та файлів, що перевіряються.

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

Іноді ви можете захотіти перевірити поле на основі іншого поля в тому ж вкладеному масиві, індекс якого вам невідомий. У таких ситуаціях ви можете дозволити вашій замиканню отримати другий аргумент, який буде поточним окремим елементом у масиві, що перевіряється:

$input = [
    'channels' => [
        [
            'type' => 'email',
            'address' => 'example@example.com',
        ],
        [
            '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(), [
    'users.*.email' => 'email|unique:users',
    'users.*.first_name' => 'required_with:users.*.last_name',
]);

Так само, ви можете використовувати символ * при вказуванні власних повідомлень валідації у ваших мовних файлах, що робить легким використання одного повідомлення валідації для полів на основі масивів:

'custom' => [
'users.*.email' => [
'unique' => 'Кожен користувач повинен мати унікальну електронну адресу',
]
],

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

Іноді вам може знадобитися отримати значення для заданого вкладеного елемента масиву при призначенні правил валідації атрибуту. Ви можете досягти цього, використовуючи метод 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' => 'Фото з моєї відпустки на пляжі!',
],
[
'name' => 'GrandCanyon.jpg',
'description' => '',
],
],
];
 
Validator::validate($input, [
'photos.*.description' => 'required',
], [
'photos.*.description.required' => 'Будь ласка, опишіть фото #: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),
    ],
]);

Перевірка типів файлів

Хоча вам потрібно вказувати лише розширення при виклику методу types, цей метод фактично перевіряє MIME-тип файлу, читаючи вміст файлу та вгадуючи його MIME-тип. Повний список MIME-типів та їх відповідних розширень можна знайти за наступним посиланням:

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

Перевірка Розмірів Файлів

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

File::types(['mp3', 'wav'])
    ->min('1kb')
    ->max('10mb');

Перевірка файлів зображень

Якщо ваш застосунок приймає зображення, завантажені вашими користувачами, ви можете використовувати метод конструктора image правила File, щоб переконатися, що файл, який перевіряється, є зображенням (jpg, jpeg, png, bmp, gif або webp).

Крім того, правило 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)),
    ],
]);

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

За замовчуванням правило image не дозволяє SVG файли через можливість вразливостей XSS. Якщо вам потрібно дозволити SVG файли, ви можете передати allowSvg: true до правила image: File::image(allowSvg: true).

Перевірка розмірів зображення

Ви також можете перевірити розміри зображення. Наприклад, щоб перевірити, що завантажене зображення має щонайменше 1000 пікселів у ширину та 500 пікселів у висоту, ви можете використовувати правило dimensions:

use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;
 
File::image()->dimensions(
    Rule::dimensions()
        ->maxWidth(1000)
        ->maxHeight(500)
)

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

Перевірка паролів

Щоб забезпечити належний рівень складності паролів, ви можете використовувати об'єкт правила Laravel Password:

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

Правило "неявне" лише передбачає, що атрибут є обов'язковим. Чи дійсно воно робить недійсним відсутній або порожній атрибут, залежить від вас.