<? phpukraine ДОКУМЕНТАЦІЯ
⌕Пошук по платформі
Документація українською

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

ВЕРСІЯ
АКТУАЛЬНА Актуальний реліз. Переклад наздоганяє оригінал, розділи з низьким відсотком позначені у змісті.
ОСНОВИ · ПЕРЕКЛАДЕНО оновлено 18 вересня 2026

Валідація · Laravel

Вступ

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

Крім того, ви можете скористатися методом validateWithBag, щоб провалідувати запит і зберегти повідомлення про помилки в іменованому контейнері помилок:

$validated = $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 автоматично перенаправить користувача на попередню сторінку. До того ж усі помилки валідації й дані запиту автоматично запишуться у flash-дані сесії.

Змінна $errors стає спільною для всіх представлень застосунку завдяки middleware Illuminate\View\Middleware\ShareErrorsFromSession, який входить до групи middleware web. Коли цей middleware застосовано, змінна $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 генерує відповідь із перенаправленням через помилку валідації, фреймворк автоматично записує всі дані запиту у flash-дані сесії. Це зроблено для того, щоб ви могли зручно звернутися до цих даних під час наступного запиту й наново заповнити форму, яку користувач намагався надіслати.

Щоб отримати flash-дані з попереднього запиту, викличте метод 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": "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."
        ]
    }
}

Валідація через form request

Створення form request

Для складніших сценаріїв валідації варто створити «form request». Form request - це власні класи запитів, які інкапсулюють свою логіку валідації й авторизації. Щоб створити клас form request, скористайтеся командою Artisan make:request:

php artisan make:request StorePostRequest

Згенерований клас form request потрапить у каталог app/Http/Requests. Якщо цього каталогу не існує, він буде створений під час виконання команди make:request. Кожен form 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.

Отже, як саме виконуються правила валідації? Усе, що потрібно, - вказати тип запиту в методі контролера. Вхідний form request валідується ще до виклику методу контролера, тобто вам не доведеться захаращувати контролер логікою валідації:

/**
 * Зберегти новий допис у блозі.
 */
public function store(StorePostRequest $request): RedirectResponse
{
    // Вхідний запит валідний...

    // Отримуємо валідовані дані...
    $validated = $request->validated();

    // Отримуємо частину валідованих даних...
    $validated = $request->safe()->only(['name', 'email']);
    $validated = $request->safe()->except(['name', 'email']);

    // Зберігаємо допис...

    return redirect('/posts');
}

Якщо валідація провалюється, генерується відповідь із перенаправленням, яка поверне користувача на попередню сторінку. Помилки також запишуться у flash-дані сесії, щоб їх можна було показати. Якщо запит був XHR-запитом, користувачеві повернеться HTTP-відповідь зі статусом 422 разом із JSON-представленням помилок валідації.

Примітка Потрібна валідація form request у реальному часі для вашого фронтенду на Inertia? Погляньте на Laravel Precognition.

Додаткова валідація

Іноді після завершення початкової валідації потрібно виконати додаткову. Це робиться за допомогою методу after form request.

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

use Illuminate\Validation\Validator;

/**
 * Отримати «after»-колбеки валідації для запиту.
 */
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;

/**
 * Отримати «after»-колбеки валідації для запиту.
 */
public function after(): array
{
    return [
        new ValidateUserStatus,
        new ValidateShippingTime,
        function (Validator $validator) {
            //
        }
    ];
}

Зупинка на першій помилці валідації

Додавши атрибут StopOnFirstFailure до класу запиту, ви можете повідомити валідатору, що він має припинити валідацію всіх атрибутів після першої ж помилки:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\Attributes\StopOnFirstFailure;
use Illuminate\Foundation\Http\FormRequest;

#[StopOnFirstFailure]
class StorePostRequest extends FormRequest
{
    // ...
}

Помилка на невідомих полях

Додавши атрибут FailOnUnknownFields до класу запиту, ви можете вказати Laravel відхиляти будь-які вхідні поля, не описані правилами валідації вашого запиту:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\Attributes\FailOnUnknownFields;
use Illuminate\Foundation\Http\FormRequest;

#[FailOnUnknownFields]
class StorePostRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'title' => ['required', 'string'],
            'body' => ['required', 'string'],
        ];
    }
}

Цю поведінку також можна ввімкнути глобально для всіх form request у AppServiceProvider:

use Illuminate\Foundation\Http\FormRequest;

/**
 * Ініціалізація сервісів застосунку.
 */
public function boot(): void
{
    FormRequest::failOnUnknownFields();
}

За потреби ви можете вимкнути цю поведінку для конкретного запиту, передавши атрибуту false:

#[FailOnUnknownFields(false)]
class PublicWebhookRequest extends FormRequest
{
    // ...
}

Відхилення невідомих полів дає додатковий захист від проблем у стилі mass assignment, бо не пропускає неочікувані ключі вхідних даних глибше в застосунок. Утім, вам усе одно слід налаштовувати властивості $fillable / $guarded моделі й зберігати лише довірені, валідовані дані.

Налаштування адреси перенаправлення

Коли валідація form request провалюється, генерується відповідь із перенаправленням, яка поверне користувача на попередню сторінку. Проте ви вільні змінити цю поведінку за допомогою атрибута RedirectTo на вашому form request:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\Attributes\RedirectTo;
use Illuminate\Foundation\Http\FormRequest;

#[RedirectTo('/dashboard')]
class StorePostRequest extends FormRequest
{
    // ...
}

Або, якщо ви хочете перенаправляти користувачів на іменований маршрут, використайте натомість атрибут RedirectToRoute:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\Attributes\RedirectToRoute;
use Illuminate\Foundation\Http\FormRequest;

#[RedirectToRoute('dashboard')]
class StorePostRequest extends FormRequest
{
    // ...
}

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

Коли валідація form request провалюється, помилки записуються у контейнер помилок default. Якщо вам потрібно зберегти їх в іншому іменованому контейнері помилок, скористайтеся атрибутом ErrorBag на вашому form request:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\Attributes\ErrorBag;
use Illuminate\Foundation\Http\FormRequest;

#[ErrorBag('login')]
class LoginRequest extends FormRequest
{
    // ...
}

Авторизація form request

Клас form request також містить метод authorize. У цьому методі ви можете визначити, чи справді автентифікований користувач має право оновити певний ресурс. Наприклад, чи справді користувач володіє коментарем у блозі, який намагається оновити. Найімовірніше, всередині цього методу ви працюватимете зі своїми gates і політиками авторизації:

use App\Models\Comment;

/**
 * Визначити, чи має користувач право виконати цей запит.
 */
public function authorize(): bool
{
    $comment = Comment::find($this->route('comment'));

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

Оскільки всі form request успадковують базовий клас запиту 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.

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

Ви можете налаштувати повідомлення про помилки, які використовує form request, перевизначивши метод 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, щоб записати повідомлення про помилки у flash-дані сесії. Коли ви використовуєте цей метод, змінна $errors після перенаправлення автоматично стане доступною у ваших представленнях, і ви легко покажете помилки користувачеві. Метод withErrors приймає валідатор, MessageBag або звичайний PHP-масив.

Зупинка на першій помилці валідації

Метод 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' => '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) {
        // ...
    },
]);

Робота з валідованими даними

Після валідації вхідних даних запиту через form request або створений вручну валідатор вам, імовірно, знадобляться самі дані, які пройшли валідацію. Отримати їх можна кількома способами. По-перше, викликати метод validated на form request чи екземплярі валідатора. Цей метод повертає масив даних, що були провалідовані:

$validated = $request->validated();

$validated = $validator->validated();

Альтернативно ви можете викликати метод safe на form request чи екземплярі валідатора. Цей метод повертає екземпляр 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 Accepted If Boolean Declined Declined If

Рядки

Active URL Alpha Alpha Dash Alpha Numeric Ascii Confirmed Current Password Different Doesnt Start With Doesnt End With Email Ends With Enum Hex Color In IP Address JSON Lowercase MAC Address Max Min Not In Regular Expression Not Regular Expression Same Size Starts With String Uppercase URL ULID UUID

Числа

Between Decimal Different Digits Digits Between Greater Than Greater Than Or Equal Integer Less Than Less Than Or Equal Max Max Digits Min Min Digits Multiple Of Numeric Same Size

Масиви

Array Array Keys Between Contains Doesnt Contain Distinct In Array In Array Keys List Max Min Size

Дати

After After Or Equal Before Before Or Equal Date Date Equals Date Format Different Timezone

Файли

Between Dimensions Encoding Extensions File Image Max Min MIME Types MIME Type By File Extension Size

База даних

Exists Unique

Утиліти

Any Of Bail Exclude Exclude If Exclude Unless Exclude With Exclude Without Filled Missing Missing If Missing Unless Missing With Missing With All Nullable Present Present If Present Unless Present With Present With All Prohibited Prohibited If Prohibited If Accepted Prohibited If Declined Prohibited Unless Prohibits Required Required If Required If Accepted Required If Declined Required Unless Required With Required With All Required Without Required Without All Required Array Keys Sometimes

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.

Коли ви тестуєте правила валідації, які виконують DNS-запити, як-от active_url та email:dns, можна скористатися методом Validator::fakeDnsLookups. Він підміняє DNS-запити, зберігаючи решту поведінки цих правил:

use Illuminate\Support\Facades\Validator;

Validator::fakeDnsLookups();

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

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

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

'username' => ['alpha_dash:ascii'],

alpha_num

Поле, що валідується, має повністю складатися з буквено-цифрових символів Unicode, що входять до \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'],
]);

Загалом варто завжди вказувати ключі масиву, які дозволено в ньому мати.

array_keys:foo,bar,...

Поле, що валідується, має бути PHP-масивом (array), усі ключі якого входять до заданого переліку. Треба вказати щонайменше один ключ:

'user' => ['array_keys:name,username'],

Для зручності можна скористатися методом Rule::arrayKeys:

'user' => [Rule::arrayKeys('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".

Параметр strict робить поле дійсним лише тоді, коли його значення дорівнює true або false:

'foo' => ['boolean:strict']

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

doesnt_contain:foo,bar,...

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

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

Validator::make($data, [
    'roles' => [
        'required',
        'array',
        Rule::doesntContain(['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

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

digits:value

Ціле число, що валідується, повинне мати рівно таку довжину, як 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, min_ratio, max_ratio.

Обмеження ratio задається як ширина, поділена на висоту. Це можна вказати або дробом на кшталт 3/2, або числом з рухомою комою на кшталт 1.5:

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

Обмеження min_ratio і max_ratio дозволяють задати діапазон допустимих співвідношень сторін:

'avatar' => ['dimensions:min_ratio=1/2,max_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),
    ],
]);

Для плинного задання обмежень співвідношення сторін також є методи minRatio, maxRatio та ratioBetween:

Rule::dimensions()->ratioBetween(min: 1 / 2, max: 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.

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

use Illuminate\Validation\Rule;

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

Валідатор dns виконує справжній DNS-запит, щоб підтвердити, що домен адреси має коректний MX-запис. Він не визначає, чи існує конкретна поштова скринька.

Ваші тести не повинні залежати від живих DNS-запитів, тому можна скористатися методом Validator::fakeDnsLookups, щоб підмінити DNS-запити, тоді як решта запитаних перевірок, як-от rfc, і далі виконуються:

use Illuminate\Support\Facades\Validator;

Validator::fakeDnsLookups();

Це дозволяє застосунку під час тестування працювати з наявними правилами валідації:

'email' => ['required', 'email:rfc,dns'],

[!WARNING] Валідатори dns і spoof потребують PHP-розширення intl.

encoding:encoding_type

Поле, що валідується, має відповідати вказаному кодуванню символів. Це правило використовує PHP-функцію mb_check_encoding для перевірки кодування заданого файлу або рядкового значення. Для зручності правило encoding можна конструювати плинним білдером правил для файлів:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;

Validator::validate($input, [
    'attachment' => [
        'required',
        File::types(['csv'])
            ->encoding('utf-8'),
    ],
]);

ends_with:foo,bar,...

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

enum

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

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 або відсутнє в даних запиту.

Якщо потрібна складна умовна логіка виключення, скористайтеся методом Rule::excludeUnless. Він приймає булеве значення або замикання. Якщо передано замикання, воно має повертати true або false, вказуючи, чи не слід виключати поле, що валідується:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

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

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

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

[!WARNING] Ніколи не покладайтеся на валідацію файлу лише за призначеним користувачем розширенням. Це правило зазвичай слід використовувати разом із правилами mimes або mimetypes.

file

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

filled

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

gt:field

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

gte:field

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

hex_color

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

image

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

[!WARNING] Типово правило image не дозволяє SVG-файли через можливі XSS-вразливості. Якщо вам потрібно дозволити SVG-файли, передайте правилу image директиву allow_svg (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

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

Параметр strict робить поле дійсним лише тоді, коли його тип - integer. Рядки з цілочисельними значеннями вважатимуться недійсними:

'age' => ['integer:strict']

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

ip

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

ipv4

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

ipv6

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

json

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

lt:field

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

lte:field

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

lowercase

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

list

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

mac_address

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

max:value

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

max_digits:value

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

mimetypes:text/plain,...

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

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

'media' => ['mimetypes:image/*,video/*'],

Щоб визначити 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

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

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

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

nullable

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

numeric

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

Параметр strict робить поле дійсним лише тоді, коли його значення має тип integer або float. Числові рядки вважатимуться недійсними:

'amount' => ['numeric:strict']

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.
  • Значення - завантажений файл із порожнім шляхом.

Якщо потрібна складна умовна логіка заборони, скористайтеся методом Rule::prohibitedUnless. Він приймає булеве значення або замикання. Якщо передано замикання, воно має повертати true або false, вказуючи, чи не слід забороняти поле, що валідується:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

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

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

prohibits:anotherfield,...

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

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

regex:pattern

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

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

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_unless потрібна складніша умова, скористайтеся методом Rule::requiredUnless. Він приймає булеве значення або замикання. Якщо передано замикання, воно має повертати true або false, вказуючи, чи не є поле, що валідується, обовʼязковим:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

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

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

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.

Для зручності правила валідації рядків також можна будувати плинним білдером правил Rule::string():

use Illuminate\Validation\Rule;

'title' => [
    'required',
    Rule::string()
        ->min(3)
        ->max(255)
        ->alphaDash(ascii: true),
],

Білдер правил для рядків надає методи для поширених обмежень: alpha, alphaDash, alphaNumeric, ascii, between, doesntEndWith, doesntStartWith, endsWith, exactly, lowercase, max, min, startsWith та uppercase. Оскільки білдер правил підтримує умови, можна також застосовувати обмеження за умовою через методи when та unless.

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']

Вказання власного зʼєднання з базою даних

Інколи потрібно задати власне зʼєднання для запитів до бази даних, які виконує Validator. Для цього додайте імʼя зʼєднання перед іменем таблиці:

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

Як змусити правило unique ігнорувати заданий ID:

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

Щоб вказати валідатору ігнорувати ID користувача, скористаємося класом Rule для плинного визначення правила.

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

[!WARNING] Ніколи не передавайте в метод 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:http,https'],

'game' => ['url:minecraft,steam'],

ulid

Поле, що валідується, має бути коректним Universally Unique Lexicographically Sortable Identifier (ULID).

uuid

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

Можна також перевірити відповідність 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.

[!NOTE] Якщо ви валідуєте поле, яке має бути присутнє завжди, але може бути порожнім, перегляньте цю примітку про необовʼязкові поля.

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

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

[!NOTE] Параметр $input, переданий у ваше замикання, буде екземпляром Illuminate\Support\Fluent і дає доступ до вхідних даних та файлів, що валідуються.

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

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

$input = [
    'channels' => [
        [
            'type' => 'email',
            'address' => 'abigail@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, правило 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'],
]);

Можна також валідувати кожен елемент масиву. Наприклад, щоб перевірити унікальність кожної email-адреси в заданому масиві:

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

Так само символ * можна вживати, задаючи власні повідомлення валідації у мовних файлах, - це дає змогу одним повідомленням покрити поля-масиви:

'custom' => [
    'users.*.email' => [
        'unique' => 'Each user 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) та :ordinal-position (починається з 1st):

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

У прикладі вище валідація не пройде, і користувач побачить помилку «Please describe photo #2.»

За потреби можна звертатися до глибше вкладених індексів і позицій через second-index, second-position, third-index, third-position тощо.

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

Валідація файлів

Laravel має набір правил для перевірки завантажених файлів: mimes, image, min, max та інші. Ці правила можна задавати поодинці, але є і зручніший варіант - плавний білдер правил для файлів:

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-типів і відповідних розширень доступний за адресою:

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

[!NOTE] Більше про валідацію розмірів зображень - у документації правила dimensions.

[!WARNING] За замовчуванням правило image не дозволяє SVG-файли через ризик XSS-вразливостей. Якщо SVG потрібні, передайте в правило image параметр allowSvg: true: 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)
);

[!NOTE] Більше про валідацію розмірів зображень - у документації правила dimensions.

Валідація паролів

Щоб паролі мали достатній рівень складності, скористайтеся обʼєктом правила 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);

// Вимагати щонайбільше 256 символів...
Password::min(16)->max(256);

// Вимагати щонайменше одну літеру...
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)
    ->max(256)
    ->letters()
    ->mixedCase()
    ->numbers()
    ->symbols()
    ->uncompromised();

Обʼєкт правила Password можна перетворити на рядок, придатний для HTML-атрибута passwordrules, методом toPasswordRulesString:

<input
    type="password"
    name="password"
    autocomplete="new-password"
    passwordrules="{{ Password::defaults()->toPasswordRulesString() }}"
/>

Визначення правил для паролів за замовчуванням

Зручно задати правила валідації паролів за замовчуванням в одному місці застосунку. Для цього є метод Password::defaults, який приймає замикання. Це замикання має повернути конфігурацію правила Password за замовчуванням. Зазвичай defaults викликають у методі boot одного з сервіс-провайдерів застосунку:

use Illuminate\Validation\Rules\Password;

/**
 * Bootstrap any application services.
 */
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 створить її під час виконання команди:

php artisan make:rule Uppercase

Коли правило створено, час описати його поведінку. Обʼєкт правила містить один метод: validate. Він отримує імʼя атрибута, його значення та колбек, який слід викликати у разі невдачі з повідомленням про помилку валідації:

<?php

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class Uppercase implements ValidationRule
{
    /**
     * Run the validation rule.
     */
    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
{
    /**
     * All of the data under validation.
     *
     * @var array<string, mixed>
     */
    protected $data = [];

    // ...

    /**
     * Set the data under validation.
     *
     * @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
{
    /**
     * The validator instance.
     *
     * @var \Illuminate\Validation\Validator
     */
    protected $validator;

    // ...

    /**
     * Set the current 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

[!WARNING] «Неявне» правило лише припускає, що атрибут обовʼязковий. Чи справді воно відхилить відсутній або порожній атрибут - вирішувати вам.

Стан перекладу

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

71%
Готовності
0
У роботі
21
Ще не перекладено
Глосарій термінів