Giới thiệu

Laravel cung cấp một số cách tiếp cận khác nhau để validate dữ liệu trong application của bạn. Một cách thông dụng nhất là sử dụng phương thức validate có sẵn trên tất cả các request HTTP đến. Tuy nhiên, chúng ta cũng sẽ thảo luận về các cách tiếp cận khác để validation.

Laravel chứa nhiều quy tắc validation tiện lợi mà bạn có thể áp dụng cho dữ liệu, thậm chí cung cấp khả năng validate nếu các giá trị là duy nhất trong một bảng cơ sở dữ liệu nhất định. Chúng tôi sẽ trình bày chi tiết từng quy tắc validation này để bạn làm quen với tất cả các tính năng validation của Laravel.

Validation Quickstart

Để tìm hiểu về các tính năng validation của Laravel, chúng ta hãy xem một ví dụ về validation cho một form và cách hiển thị thông báo lỗi cho người dùng. Bằng cách đọc phần tổng quan nâng cao này, bạn sẽ có thể hiểu rõ hơn về cách validate dữ liệu request bằng Laravel:

Định nghĩa Routes

Đầu tiên, giả sử chúng ta có các route sau đã được định nghĩa trong file routes/web.php:

use App\Http\Controllers\PostController;

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

Route GET sẽ hiển thị một form cho người dùng để tạo một bài đăng mới trong blog, trong khi route POST sẽ lưu trữ bài đăng đó vào trong blog trong cơ sở dữ liệu.

Tạo Controller

Tiếp theo, chúng ta hãy xem một controller đơn giản xử lý các request đến route này. Bây giờ chúng ta sẽ bỏ trống phương thức store:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\View;

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

    /**
     * Store a new blog post.
     */
    public function store(Request $request): RedirectResponse
    {
        // Validate and store the blog post...

        $post = /** ... */

        return to_route('post.show', ['post' => $post->id]);
    }
}

Viết Validation Logic

Bây giờ chúng ta đã sẵn sàng để viết vào phương thức store của chúng ta với các logic validate bài đăng trong blog. Để làm điều này, chúng ta sẽ sử dụng phương thức validate được cung cấp trong đối tượng Illuminate\Http\Request. Nếu pass qua validate rule, code của bạn sẽ được tiếp tục thực thi bình thường; tuy nhiên, nếu validate không thành công, một Illuminate\Validation\ValidationException exception sẽ được đưa ra và một error response thích hợp sẽ tự động được gửi về cho người dùng.

Nếu validation thất bại trong một request HTTP bình thường, thì một response chuyển hướng tới URL trước đó sẽ được tạo. Nếu request đến là một request XHR thì một response JSON chứa thông báo lỗi validation sẽ được trả về.

Để hiểu rõ hơn về phương thức validate, chúng ta hãy quay lại phương thứcstore:

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

    // The blog post is valid...

    return redirect('/posts');
}

Như bạn có thể thấy, các quy tắc validation đã được truyền vào phương thức validate. Đừng lo lắng - tất cả các quy tắc validation có sẵn đều có tài liệu. Một lần nữa, nếu validation thất bại, một response thích hợp sẽ được tự động trả về. Còn nếu validation thành công, controller của chúng ta sẽ tiếp tục được thực thi bình thường.

Ngoài ra, các quy tắc validation có thể được chỉ định dưới dạng các mảng quy tắc thay vì một chuỗi phân cách bằng dấu |:

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

Ngoài ra, bạn có thể sử dụng phương thức validateWithBag để kiểm tra một request và lưu bất kỳ thông báo lỗi nào vào trong một named error bag:

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

Dừng luôn nếu Validation đầu tiên thất bại

Đôi khi bạn có thể muốn dừng chạy quy tắc validation trên một thuộc tính sau lần thất bại đầu tiên. Để làm như vậy, hãy gán quy tắc bail cho thuộc tính:

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

Trong ví dụ này, nếu quy tắc unique trong thuộc tính title thất bại, quy tắc max sẽ không được kiểm tra. Các quy tắc này sẽ được validate theo thứ tự mà chúng được định nghĩa.

Lưu ý về các thuộc tính lồng nhau

Nếu incoming request HTTP chứa một field dữ liệu "lồng nhau", bạn có thể định nghĩa field này trong quy tắc validation bằng cách sử dụng cú pháp "chấm":

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

Mặt khác, nếu tên field của bạn có chứa dấu chấm, thì bạn có thể ngăn chặn điều này khỏi bị hiểu nhầm là cú pháp "dấu chấm" bằng cách thêm dấu gạch chéo đằng trước dấu chấm:

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

Hiển thị Validation Errors

Vậy, điều gì sẽ xảy ra nếu các field request không pass qua các quy tắc validation đã cho? Như đã đề cập trước đó, Laravel sẽ tự động chuyển hướng người dùng trở lại vị trí trước đó của họ. Ngoài ra, tất cả các lỗi validation và các request input sẽ được tự động flash vào trong session.

Biến $errors sẽ được chia sẻ với tất cả view trong ứng dụng của bạn thông qua middleware Illuminate\View\Middleware\ShareErrorsFromSession, được cung cấp bởi group middleware web. Khi middleware này được áp dụng, thì biến $errors này sẽ luôn có tồn tại trong view của bạn, cho phép bạn giả sử biến $errors luôn được khai báo và có thể được sử dụng một cách an toàn hơn. Biến $errors sẽ là một instance của Illuminate\Support\MessageBag. Để biết thêm thông tin về cách làm việc với đối tượng này, hãy xem tài liệu về nó.

Vì vậy, trong ví dụ của chúng ta, người dùng sẽ được chuyển hướng về phương thức create của controller khi validation thất bại, cho phép chúng ta hiển thị các thông báo lỗi trong view như sau:

<!-- /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 -->

Tùy biến Error Messages

Mỗi quy tắc validation có sẵn của Laravel đều có một thông báo lỗi nằm trong file lang/en/validation.php trong ứng dụng của bạn. Nếu ứng dụng của bạn không có thư mục lang, bạn có thể bắt Laravel tạo thư mục này bằng lệnh Artisan lang:publish.

Trong file lang/en/validation.php, bạn sẽ tìm thấy các thông báo lỗi đã được dịch cho từng quy tắc validation. Bạn có thể tự do thay đổi hoặc sửa đổi những thông báo này dựa trên nhu cầu của ứng dụng của bạn.

Ngoài ra, bạn có thể copy file này sang thư mục ngôn ngữ khác để dịch các thông báo lỗi cho ngôn ngữ đó cho ứng dụng của bạn. Để tìm hiểu thêm về localization Laravel, hãy xem tài liệu về localization.

[!WARNING] Mặc định, framework ứng dụng Laravel không chứa thư mục lang. Nếu bạn muốn tùy chỉnh các file ngôn ngữ của Laravel, bạn có thể export chúng thông qua lệnh Artisan lang:publish.

XHR Requests và Validation

Trong ví dụ này, chúng tôi đã sử dụng form truyền thống để gửi dữ liệu đến ứng dụng. Tuy nhiên, nhiều ứng dụng sẽ nhận được request XHR từ frontend được hỗ trợ bởi JavaScript. Khi sử dụng phương thức validate trong request XHR, Laravel sẽ không tạo response chuyển hướng. Mà thay vào đó, Laravel tạo ra một response JSON chứa tất cả các lỗi validation. Response JSON này sẽ được gửi cùng với mã trạng thái HTTP 422.

The @error Directive

Bạn có thể sử dụng lệnh @error Blade để xác định xem trong thông báo lỗi validation có tồn tại cho một thuộc tính hay không. Trong lệnh @error, bạn có thể echo ra biến $message để hiển thị thông báo lỗi:

<!-- /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

Nếu đang sử dụng error bag có tên, bạn có thể truyền tên của error bag đó làm tham số thứ hai cho lệnh @error:

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

Repopulating Forms

Khi Laravel tạo response chuyển hướng do lỗi validation, framework sẽ tự động chuyển tất cả thông tin input của request vào session. Điều này được thực hiện để bạn có thể lấy ra thông tin input một cách thuận tiện trong lần request tiếp theo và điền lại vào form mà người dùng đã cố gắng gửi.

Để lấy ra dữ liệu input đã được flash từ request trước đó, hãy gọi phương thức old trên instance của Illuminate\Http\Request. Phương thức old sẽ lấy dữ liệu input đã được flash trước đó từ session:

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

Laravel cũng cung cấp một helper global old. Nếu bạn đang muốn hiển thị thông tin cũ vào trong Blade, thì sẽ thuận tiện hơn khi sử dụng helper old để điền lại vào form. Nếu không có dữ liệu cũ tồn tại cho field đã cho, giá trị null sẽ được trả về:

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

Lưu ý về các field tùy chọn

Mặc định, Laravel sẽ chứa hai middleware là: TrimStringsConvertEmptyStringsToNull trong stack middleware global application. Vì thế, bạn sẽ cần phải đánh dấu các trường request "optional" của bạn là nullable nếu bạn không muốn validator coi các giá trị null của các trường này là không hợp lệ. Ví dụ:

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

Trong ví dụ trên, chúng ta đang định nghĩa là trường publish_at có thể là null hoặc nếu có giá trị thì phải theo format của date. Nếu chúng ta không thêm nullable vào trong định nghĩa quy tắc này, thì validator sẽ coi null là một date không hợp lệ.

Định dạng response validation error

Khi ứng dụng của bạn đưa ra ngoại lệ Illuminate\Validation\ValidationException và incoming request HTTP đến đang mong đợi một response JSON, thì Laravel sẽ tự động định dạng thông báo lỗi cho bạn và trả về một response HTTP 422 Unprocessable Entity.

Dưới đây, bạn có thể xem một ví dụ mẫu về định dạng response JSON cho lỗi xác thực. Lưu ý rằng các khóa lỗi lồng nhau đã được làm ngang hàng thông qua định dạng ký hiệu "dấu chấm":

{
    "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 Validation

Tạo Form Requests

Đối với các kịch bản validation phức tạp hơn, bạn có thể tạo một "form request". Form request là các class request tùy biến đóng gói các logic validation và logic authorization. Để tạo một class form request, bạn có thể sử dụng lệnh Artisan CLI make:request:

php artisan make:request StorePostRequest

Class form request được tạo ra sẽ được lưu trong thư mục app/Http/Requests. Nếu thư mục này không tồn tại, nó sẽ được tạo khi bạn chạy lệnh make:request. Mỗi form request do Laravel tạo ra có hai phương thức: authorizerules.

Như bạn có thể thấy, phương thức authorize sẽ chịu trách nhiệm xác định xem người dùng hiện tại có thể thực hiện hành động hay không, trong khi phương thức rules sẽ trả về các quy tắc validation sẽ áp dụng cho dữ liệu của request:

/**
 * Get the validation rules that apply to the request.
 *
 * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
 */
public function rules(): array
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

[!NOTE] Bạn có thể khai báo bất kỳ phụ thuộc nào mà bạn muốn trong phương thức rule. Những phụ thuộc đó sẽ được tự động resolve thông qua Laravel service container.

Vậy, các quy tắc validation sẽ được so sánh như thế nào? Tất cả những gì bạn cần làm là khai báo nó cho request trong phương thức controller của bạn. Form request đến sẽ được validate trước khi phương thức controller được gọi, nghĩa là bạn không cần làm lộn xộn controller của bạn với bất kỳ logic validate nào:

/**
 * Store a new blog post.
 */
public function store(StorePostRequest $request): RedirectResponse
{
    // The incoming request is valid...

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

    // Retrieve a portion of the validated input data...
    $validated = $request->safe()->only(['name', 'email']);
    $validated = $request->safe()->except(['name', 'email']);

    // Store the blog post...

    return redirect('/posts');
}

Nếu validation thất bại, một response chuyển hướng sẽ được tạo và đưa người dùng trở về vị trí trước đó của họ. Các lỗi cũng sẽ được flash vào session để chúng có thể được hiển thị. Nếu request là loại request XHR, response HTTP có status code 422 sẽ được trả về cho người dùng chứa một data JSON gồm các lỗi validation.

[!NOTE] Bạn cần thêm một form validation request real-time vào Inertia của bạn, cái mà được cung cấp bởi Laravel frontend? Hãy xem Laravel Precognition.

Performing Additional Validation

Thỉnh thoảng bạn cần thực hiện thêm một validation bổ sung sau khi cài đặt validation của bạn hoàn thành. Bạn có thể thực hiện nó bằng cách dùng phương thức after của request.

Phương thức after sẽ cần trả về một mảng các callback hoặc closure, cái mà sẽ được gọi sau khi validation hoàn thành. Cái hàm callback sẽ nhận vào một instance Illuminate\Validation\Validator, cho phép bạn đưa thêm vào các error message nếu cần thiết:

use Illuminate\Validation\Validator;

/**
 * Get the "after" validation callables for the request.
 */
public function after(): array
{
    return [
        function (Validator $validator) {
            if ($this->somethingElseIsInvalid()) {
                $validator->errors()->add(
                    'field',
                    'Something is wrong with this field!'
                );
            }
        }
    ];
}

Hãy chú ý rằng, mảng mà được trả về bởi hàm after cũng là một class có thể gọi lại. Phương thức __invoke của class này sẽ nhận vào một instance Illuminate\Validation\Validator:

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;
use Illuminate\Validation\Validator;

/**
 * Get the "after" validation callables for the request.
 */
public function after(): array
{
    return [
        new ValidateUserStatus,
        new ValidateShippingTime,
        function (Validator $validator) {
            //
        }
    ];
}

Stopping On First Validation Failure Attribute

Bằng cách thêm một thuộc tính StopOnFirstFailure vào request class của bạn, bạn có thể thông báo cho validator rằng nó sẽ phải ngừng kiểm tra các thuộc tính khác sau khi đã xảy ra một lỗi validation:

<?php

namespace App\Http\Requests;

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

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

Failing on Unknown Fields

Bằng cách thêm thuộc tính FailOnUnknownFields vào request class của bạn, bạn có thể chỉ định Laravel từ chối bất kỳ field nào gửi lên mà không định nghĩa trước trong các validation rule thuộc request của bạn:

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

Bạn cũng có thể cấu hình để enable hành vi này cho tất cả các form request từ trong AppServiceProvider:

use Illuminate\Foundation\Http\FormRequest;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    FormRequest::failOnUnknownFields();
}

Nếu cần, bạn có thể disable hành vi này cho một request cụ thể bằng cách truyền false cho thuộc tính:

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

Việc từ chối các unknown field có thể cung cấp thêm một lớp bảo vệ chống lại các vấn đề kiểu mass-assignment bằng cách ngăn các input key không mong muốn truyền sâu hơn vào ứng dụng của bạn. Tuy nhiên, bạn vẫn nên thiết lập các thuộc tính $fillable / $guarded cho model của bạn và chỉ lưu trữ các input đã được validate đáng tin cậy.

Customizing The Redirect Location

Khi xác thực form request không thành công, một response chuyển hướng sẽ được tạo để đưa người dùng quay lại vị trí trước đó của họ. Tuy nhiên, bạn có thể tự do tùy chỉnh hành vi này. Để làm như vậy, bạn có thể sử dụng thuộc tính RedirectTo trên form request của bạn:

<?php

namespace App\Http\Requests;

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

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

Hoặc, nếu bạn muốn chuyển hướng người dùng đến một route đã được đặt tên, bạn có thể sử dụng thuộc tính RedirectToRoute để định nghĩa:

<?php

namespace App\Http\Requests;

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

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

Customizing the Error Bag

Khi xác thực form request mà không thành công, các lỗi sẽ được đưa vào error bag default. Nếu bạn cần lưu các lỗi vào trong một error bag có tên khác, bạn có thể sử dụng attribute ErrorBag trên form request của bạn:

<?php

namespace App\Http\Requests;

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

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

Authorizing Form Requests

Class form request cũng chứa một phương thức authorize. Trong phương thức này, bạn có thể xác định xem người dùng hiện tại thực sự có quyền truy cập vào resource này hay không. Ví dụ: bạn có thể xác định xem người dùng có thực sự là chủ sở hữu của một bình luận trong blog mà họ đang cố cập nhật hay không. Rất có thể, bạn sẽ tương tác với các authorization gate và các policy của bạn trong phương thức này:

use App\Models\Comment;

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

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

Vì tất cả các form request đều được mở rộng từ class request của Laravel, nên chúng ta có thể sử dụng phương thức user để truy cập vào người dùng hiện tại đang được authenticate. Hãy lưu ý cách gọi đến phương thức route trong ví dụ ở trên. Phương thức này cung cấp cho bạn quyền truy cập vào các tham số URI đã được định nghĩa trên route hiện tại, chẳng hạn như tham số {comment} trong ví dụ bên dưới:

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

Do đó, nếu ứng dụng của bạn đang tận dụng liên kết model route, thì code của bạn có thể trở nên ngắn gọn hơn nữa bằng cách truy cập vào một resolve model dưới dạng một thuộc tính của request:

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

Nếu phương thức authorize trả về false, một HTTP response có status code là 403 sẽ được tự động trả về và phương thức trong controller của bạn sẽ không được thực thi.

Nếu bạn có dự định xử lý logic authorization cho request nằm ở trong một phần khác của application, bạn có thể xoá hoàn toàn phương thức authorize, hoặc chỉ đơn giản là trả về true:

/**
 * Determine if the user is authorized to make this request.
 */
public function authorize(): bool
{
    return true;
}

[!NOTE] Bạn có thể khai báo bất kỳ phụ thuộc nào mà bạn cần trong phương thức authorize. Những phụ thuộc đó sẽ được tự động resolve thông qua Laravel service container.

Tùy biến Error Messages

Bạn có thể tùy biến các thông báo lỗi được sử dụng bởi form request bằng cách ghi đè phương thức messages. Phương thức này sẽ trả về một mảng gồm các cặp thuộc tính / quy tắc và các thông báo lỗi tương ứng của chúng:

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

Tùy biến thuộc tính Validation

Nhiều thông báo lỗi của quy tắc validation có sẵn của Laravel chứa phần biến :attribute. Nếu bạn muốn biến :attribute của message validation được thay thế bằng tên một thuộc tính tùy chỉnh, bạn có thể chỉ định các tên tùy chỉnh đó bằng cách ghi đè phương thức attributes. Phương thức này sẽ trả về một mảng gồm thuộc tính và tên:

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

Chuẩn bị dữ liệu cho Validation

Nếu bạn cần chuẩn bị hoặc làm sạch dữ liệu trong request trước khi áp dụng các quy tắc validation của bạn, bạn có thể sử dụng phương thức prepareForValidation:

use Illuminate\Support\Str;

/**
 * Prepare the data for validation.
 */
protected function prepareForValidation(): void
{
    $this->merge([
        'slug' => Str::slug($this->slug),
    ]);
}

Tương tự như vậy, nếu bạn cần chuẩn hóa bất kỳ dữ liệu nào của request sau khi xác thực hoàn tất, bạn có thể sử dụng phương thức passedValidation:

/**
 * Handle a passed validation attempt.
 */
protected function passedValidation(): void
{
    $this->replace(['name' => 'Taylor']);
}

Tạo Validator thủ công

Nếu bạn không muốn sử dụng phương thức validate theo request, bạn có thể tự tạo một instance validator bằng cách sử dụng facade Validator. Phương thức make trên facade sẽ tạo ra một instance validator mới:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class PostController extends Controller
{
    /**
     * Store a new blog post.
     */
    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();
        }

        // Retrieve the validated input...
        $validated = $validator->validated();

        // Retrieve a portion of the validated input...
        $validated = $validator->safe()->only(['name', 'email']);
        $validated = $validator->safe()->except(['name', 'email']);

        // Store the blog post...

        return redirect('/posts');
    }
}

Tham số đầu tiên được truyền cho phương thức make là dữ liệu cần được validation. Tham số thứ hai là một mảng các quy tắc validation sẽ được áp dụng cho dữ liệu đó.

Sau khi xác định request validation bị thất bại, bạn có thể sử dụng phương thức withErrors để flash các thông báo lỗi vào session. Khi sử dụng phương thức này, biến $errors sẽ được tự động chia sẻ với các view của bạn sau khi được chuyển hướng tới, cho phép bạn dễ dàng hiển thị thông báo lỗi cho người dùng. Phương thức withErrors chấp nhận một validator và một MessageBag hoặc một PHP array.

Stopping On First Validation Failure

Phương thức stopOnFirstFailure sẽ thông báo cho validator rằng nó sẽ phải ngừng kiểm tra các thuộc tính khác sau khi đã xảy ra một lỗi validation:

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

Tự dộng chuyển hướng

Nếu bạn muốn tự tạo một validator instance nhưng vẫn muốn tận dụng tính năng chuyển hướng tự động được cung cấp bởi phương thức validate của HTTP request, bạn có thể gọi phương thức validate trên một validator instance đã tồn tại. Nếu validation thất bại, người dùng sẽ tự động được chuyển hướng hoặc trong trường hợp request là XHR, thì một response JSON sẽ được trả về:

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

Bạn có thể sử dụng phương thức validateWithBag để lưu thông báo lỗi vào trong một named error bag nếu quá trình kiểm tra không thành công:

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

Tên của Error Bags

Nếu bạn có nhiều form trong một trang, bạn có thể muốn đặt tên cho MessageBag chứa các lỗi validation, cho phép bạn có thể truy xuất vào các thông báo lỗi cho một form cụ thể. Để đạt được điều này, hãy truyền tên đó làm tham số thứ hai cho phương thức withErrors:

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

Sau đó, bạn có thể truy cập vào instance MessageBag đã được đặt tên từ biến $errors:

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

Tùy biến Error Messages

Nếu cần, bạn có thể cung cấp một tùy biến thông báo lỗi cho validation thay vì mặc định. Có một số cách để định nghĩa tùy biến một thông báo lỗi. Đầu tiên, bạn có thể truyền các thông báo lỗi đã được tùy biến làm tham số thứ ba cho phương thức Validator::make:

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

Trong ví dụ này, :attribute sẽ được thay thế bằng tên thực sự của field mà được validation. Bạn cũng có thể sử dụng các attribute khác trong validation messages. Ví dụ:

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

Specifying A Custom Message For A Given Attribute

Thỉnh thoảng bạn có thể chỉ định một thông báo lỗi tùy biến chỉ cho một field cụ thể. Bạn có thể làm như vậy bằng cách dùng ký hiệu "chấm". Chỉ định tên của attribute trước và sau đó là đến tên của quy tắc:

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

Specifying Custom Attribute Values

Nhiều thông báo lỗi có sẵn của Laravel có chứa một biến :attribute có thể được thay thế bằng tên của một field hoặc một thuộc tính đang được validation. Để tùy chỉnh các giá trị được sử dụng để thay thế cho biến này cho các field cụ thể, bạn có thể truyền một mảng thuộc tính tùy biến làm tham số thứ tư cho phương thức Validator::make:

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

Thực hiện Validation bổ sung

Sometimes you need to perform additional validation after your initial validation is complete. You can accomplish this using the validator's after method. The after method accepts a closure or an array of callables which will be invoked after validation is complete. The given callables will receive an Illuminate\Validation\Validator instance, allowing you to raise additional error messages if necessary:

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()) {
    // ...
}

Hãy chú ý rằng, phương thức after cũng chấp nhận một mảng các callback, which is particularly convenient if your "after validation" logic is encapsulated in invokable classes, which will receive an Illuminate\Validation\Validator instance via their __invoke method:

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;

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

Làm việc với Validated Input

Sau khi validate dữ liệu request đến bằng cách sử dụng một request form hoặc instance validator, bạn có thể muốn lấy ra dữ liệu request đã thực sự trải qua quá trình validation. Điều này có thể được thực hiện bằng nhiều cách. Đầu tiên, bạn có thể gọi phương thức validated trên một request form hoặc instance validator. Phương thức này sẽ trả về một mảng dữ liệu đã được validate:

$validated = $request->validated();

$validated = $validator->validated();

Ngoài ra, bạn có thể gọi phương thức safe trên một request form hoặc instance validator. Phương thức này sẽ trả về một instancen của Illuminate\Support\ValidatedInput. Đối tượng này có thêm các phương thức only, except, và all để lấy ra một tập con của dữ liệu được validate hoặc toàn bộ dữ liệu được validate:

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

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

$validated = $request->safe()->all();

Ngoài ra, instance Illuminate\Support\ValidatedInput có thể lặp được và truy cập giống như một mảng:

// Validated data may be iterated...
foreach ($request->safe() as $key => $value) {
    // ...
}

// Validated data may be accessed as an array...
$validated = $request->safe();

$email = $validated['email'];

Nếu bạn muốn thêm các field vào trong dữ liệu đã validate, bạn có thể gọi phương thức merge:

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

Nếu bạn muốn lấy ra dữ liệu đã được validate dưới dạng một instance collection, bạn có thể gọi phương thức collect:

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

Làm việc với Error Messages

Sau khi gọi phương thức errors trong một instance Validator, bạn sẽ nhận về một instance Illuminate\Support\MessageBag, có nhiều phương thức để làm việc với các thông báo lỗi. Biến $errors mà được tự động cung cấp cho các view cũng là một instance của class MessageBag.

Lấy lỗi đầu tiên của một field

Để lấy thông báo lỗi đầu tiên cho một field, hãy sử dụng phương thức first:

$errors = $validator->errors();

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

Lấy tất cả các lỗi của một field

Nếu bạn cần lấy tất cả các thông báo lỗi cho một field, hãy sử dụng phương thức get:

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

Nếu bạn đang validate một mảng field, bạn có thể lấy tất cả các thông báo lỗi cho từng field trong mảng bằng ký tự *:

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

Lấy tất cả các lỗi của tất cả các field

Để lấy một mảng tất cả các thông báo lỗi cho tất cả các field, hãy sử dụng phương thức all:

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

Xác định một thông báo có tồn tại của một field

Phương thức has có thể được sử dụng để xác định xem có tồn tại thông báo lỗi nào cho field đã cho không:

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

Chỉ định Message tùy chỉnh trong Language Files

Mỗi quy tắc validation có sẵn của Laravel đều có một thông báo lỗi nằm trong file lang/en/validation.php trong ứng dụng của bạn. Nếu ứng dụng của bạn không chứa một thư mục lang, bạn có thể hướng dẫn Laravel tạo thư mục đó bằng lệnh Artisan lang:publish.

Trong file lang/en/validation.php, bạn sẽ tìm thấy các thông báo lỗi đã được dịch cho từng quy tắc validation. Bạn có thể tự do thay đổi hoặc sửa đổi những thông báo này dựa trên nhu cầu của ứng dụng của bạn.

Ngoài ra, bạn có thể copy file này sang thư mục ngôn ngữ khác để dịch các thông báo lỗi cho ngôn ngữ đó cho ứng dụng của bạn. Để tìm hiểu thêm về localization Laravel, hãy xem tài liệu về localization.

[!WARNING] Mặc định, framework Laravel không chứa thư mục lang. Nếu bạn muốn tùy chỉnh các file ngôn ngữ của Laravel, bạn có thể export ra chúng thông qua lệnh Artisan lang:publish.

Custom Messages For Specific Attributes

Bạn có thể tùy chỉnh các thông báo lỗi được sử dụng cho các kết hợp giữa thuộc tính và quy tắc được trong các file ngôn ngữ validation trong ứng dụng của bạn. Để làm như vậy, bạn hãy thêm các tùy chỉnh thông báo của bạn vào mảng custom của file ngôn ngữ lang/xx/validation.php của ứng dụng của bạn:

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

Chỉ định Attributes trong Language Files

Nhiều thông báo lỗi có sẵn của Laravel có chứa một biến :attribute có thể được thay thế bằng tên của một field hoặc một thuộc tính đang được validation. Nếu bạn muốn phần :attribute trong thông báo validation của bạn được thay thế bằng một giá trị tùy biến, bạn có thể chỉ định tên attribute tùy biến này trong mảng attributes của file language lang/xx/validation.php:

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

[!WARNING] Mặc định, framework Laravel không chứa thư mục lang. Nếu bạn muốn tùy chỉnh các file ngôn ngữ của Laravel, bạn có thể export ra chúng thông qua lệnh Artisan lang:publish.

Chỉ định Values trong Language Files

Một số thông báo lỗi cua quy tắc validation có sẵn của Laravel có chứa một biến :value được thay thế cho giá trị hiện tại của một thuộc tính request. Tuy nhiên, đôi khi bạn có thể cần thay thế biến :value của thông báo validation bằng một giá trị tùy chỉnh. Ví dụ: hãy xem xét quy tắc sau sẽ yêu cầu rằng số thẻ tín dụng phải là bắt buộc nếu thuộc tính payment_type có giá trị là cc:

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

Nếu rule validation này không thành công, thì nó sẽ tạo ra một thông báo lỗi như sau:

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

Thay vì hiển thị cc làm giá trị của payment type, bạn có thể chỉ định một giá trị tùy biến thân thiện với người dùng hơn trong file ngôn ngữ lang/xx/validation.php của bạn bằng cách định nghĩa mảng values:

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

[!WARNING] Mặc định, framework Laravel không chứa thư mục lang. Nếu bạn muốn tùy chỉnh các file ngôn ngữ của Laravel, bạn có thể export ra chúng thông qua lệnh Artisan lang:publish.

Sau khi định nghĩa giá trị này, rule validation sẽ tạo ra thông báo lỗi như sau:

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

Các Validation Rule có sẵn

Dưới đây là danh sách tất cả các quy tắc validation có sẵn và chức năng của chúng:

Booleans

Strings

Numbers

Arrays

Dates

Files

Database

Utilities

accepted

Field được validation phải là "yes", "on", 1, "1", true, hoặc "true". Điều này hữu ích để validation chấp nhận "Điều khoản dịch vụ" hoặc các field giống nhau.

accepted_if:anotherfield,value,...

Field được validation phải là "yes", "on", 1, "1", true, hoặc "true" nếu một field khác đang được validation bằng một giá trị được chỉ định. Điều này hữu ích để validation chấp nhận "Điều khoản dịch vụ" hoặc các field giống nhau.

active_url

Field được validation phải có bản ghi A hoặc AAAA hợp lệ theo hàm PHP dns_get_record. Hostname của URL đã cung cấp sẽ được lấy bằng cách sử dụng hàm PHP parse_url trước khi được truyền đến dns_get_record.

after:date

Field được validation phải là một giá trị sau một ngày nhất định. Tham số date sẽ được truyền vào hàm PHP strtotime để được chuyển thành instance DateTime hợp lệ:

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

Thay vì truyền một chuỗi date được chạy bởi hàm strtotime, bạn có thể chỉ định một field khác để so sánh với ngày:

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

Để thuận tiện, các quy tắc dựa trên date có thể được xây dựng bằng cách sử dụng builder rule date:

use Illuminate\Validation\Rule;

'start_date' => [
    'required',
    Rule::date()->after(today()->addDays(7)),
],

Các phương thức afterTodaytodayOrAfter có thể được sử dụng để diễn đạt một cách trôi chảy hơn, ngày đang validate phải là ngày hiện tại, hoặc là một ngày trong tương lai:

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

after_or_equal:date

Field được validation phải là một giá trị sau hoặc bằng ngày đã cho. Để biết thêm thông tin, hãy xem quy tắc after.

Để thuận tiện, các quy tắc dựa trên date có thể được xây dựng bằng cách sử dụng builder rule date:

use Illuminate\Validation\Rule;

'start_date' => [
    'required',
    Rule::date()->afterOrEqual(today()->addDays(7)),
],

anyOf

Quy tắc validation Rule::anyOf cho phép bạn chỉ định field đang được validate phải thỏa mãn bất kỳ bộ quy tắc validation nào được cung cấp. Ví dụ: quy tắc sau đây sẽ xác thực rằng field username phải là địa chỉ email hoặc một chuỗi ký tự chữ và số (bao gồm cả dấu gạch ngang) có độ dài ít nhất là 6 ký tự:

use Illuminate\Validation\Rule;

'username' => [
    'required',
    Rule::anyOf([
        ['string', 'email'],
        ['string', 'alpha_dash', 'min:6'],
    ]),
],

alpha

Field được validation phải hoàn toàn là các ký tự chữ cái Unicode có trong \p{L}\p{M}.

Để giới hạn quy tắc validation này đối với các ký tự có trong phạm vi ASCII (a-zA-Z), bạn có thể cung cấp thêm tùy chọn ascii cho quy tắc validation:

'username' => 'alpha:ascii',

alpha_dash

Field được validation phải hoàn toàn là các ký tự chữ và số Unicode có trong \p{L}, \p{M}, \p{N}, cũng như dấu gạch ngang ASCII (-) và dấu gạch dưới ASCII (_).

Để giới hạn quy tắc validation này đối với các ký tự có trong phạm vi ASCII (a-z, A-Z, và 0-9), bạn có thể cung cấp thêm tùy chọn ascii cho quy tắc validation:

'username' => 'alpha_dash:ascii',

alpha_num

Field được validation phải hoàn toàn là các ký tự chữ và số Unicode có trong \p{L}, \p{M}, và \p{N}.

Để giới hạn quy tắc validation này đối với các ký tự có trong phạm vi ASCII (a-z, A-Z, và 0-9), bạn có thể cung cấp thêm tùy chọn ascii cho quy tắc validation:

'username' => 'alpha_num:ascii',

array

Field được validation phải là một PHP array.

Khi các giá trị được cung cấp thêm cho quy tắc array, thì mỗi khóa trong mảng input phải có trong danh sách các giá trị được cung cấp cho quy tắc. Trong ví dụ sau, khóa admin trong mảng input không hợp lệ vì nó không có trong danh sách các giá trị được cung cấp cho quy tắc array:

use Illuminate\Support\Facades\Validator;

$input = [
    'user' => [
        'name' => 'Taylor Otwell',
        'username' => 'taylorotwell',
        'admin' => true,
    ],
];

Validator::make($input, [
    'user' => 'array:name,username',
]);

Nói chung, bạn phải luôn chỉ định các khóa trong mảng được phép có mặt trong mảng của bạn.

ascii

Field được validation phải hoàn toàn là các ký tự ASCII 7 bit.

bail

Dừng chạy các validation rule cho field nếu lần validation đầu tiên không thành công.

Mặc dù quy tắc bail sẽ ngừng validate một field cụ thể khi nó gặp một lỗi validation, nhưng phương thức stopOnFirstFailure sẽ thông báo cho validator rằng nó sẽ ngừng validate tất cả các thuộc tính sau khi xảy ra một lỗi validation:

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

before:date

Field được validation là một giá trị trước ngày đã cho. Tham số date sẽ được truyền vào hàm strtotime của PHP để được chuyển thành instance DateTime hợp lệ. Ngoài ra, giống như quy tắc after, tên của một field khác cũng có thể được cung cấp dưới dạng như một giá trị kiểu date.

Để thuận tiện, các quy tắc dựa trên date có thể được xây dựng bằng cách sử dụng builder rule date:

use Illuminate\Validation\Rule;

'start_date' => [
    'required',
    Rule::date()->before(today()->subDays(7)),
],

Các phương thức beforeTodaytodayOrBefore có thể được sử dụng để diễn đạt một cách trôi chảy hơn, ngày đang validate phải là ngày hiện tại hoặc là một ngày trong quá khứ:

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

before_or_equal:date

Field được validation là một giá trị trước hoặc bằng với ngày đã cho. Tham số date sẽ được truyền vào hàm strtotime của PHP để được chuyển thành instance DateTime hợp lệ. Ngoài ra, giống như quy tắc after, tên của một field khác cũng có thể được cung cấp dưới dạng như một giá trị kiểu date.

Để thuận tiện, các quy tắc dựa trên date có thể được xây dựng bằng cách sử dụng builder rule date:

use Illuminate\Validation\Rule;

'start_date' => [
    'required',
    Rule::date()->beforeOrEqual(today()->subDays(7)),
],

between:min,max

Field được validation phải có kích thước ở giữa (hoặc bằng) minmax đã cho. Chuỗi, số, mảng và file sẽ được so sánh theo cùng một quy tắc với quy tắc size.

boolean

Field được validation phải có thể được cast là boolean. Input được chấp nhận là true, false, 1, 0, "1", và "0".

Bạn có thể sử dụng tham số strict để coi field này là hợp lệ khi giá trị của nó chỉ duy nhất là true hoặc false:

'foo' => 'boolean:strict'

confirmed

Field được validation phải có field là {field}_confirmation. Ví dụ: nếu field được validation là password, thì field password_confirmation phải có tồn tại trong input.

Bạn cũng có thể truyền vào một tên field confirmation tùy biến. Ví dụ, confirmed:repeat_username sẽ yêu cầu field repeat_username phải khớp với field đang được validation.

contains:foo,bar,...

Field được validation phải là một mảng chứa tất cả các giá trị được cung cấp. Vì rule này sẽ yêu cầu bạn phải sử dụng hàm implode để tạo một mảng, nên phương thức Rule::contains có thể được sử dụng để xây dựng rule này một cách rõ ràng nhất:

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

Validator::make($data, [
    'roles' => [
        'required',
        'array',
        Rule::contains(['admin', 'editor']),
    ],
]);

doesnt_contain:foo,bar,...

Field được validation phải là một mảng không chứa bất kỳ giá trị tham số nào được cung cấp. Vì rule này sẽ yêu cầu bạn phải sử dụng hàm implode để tạo một mảng, nên phương thức Rule::doesntContain có thể được sử dụng để xây dựng rule này một cách rõ ràng nhất:

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

Validator::make($data, [
    'roles' => [
        'required',
        'array',
        Rule::doesntContain(['admin', 'editor']),
    ],
]);

current_password

Field được validation phải khớp với mật khẩu của người dùng hiện tại. Bạn có thể chỉ định authentication guard bằng cách sử dụng tham số đầu tiên của quy tắc:

'password' => 'current_password:api'

date

Field được validation phải là một ngày hợp lệ và non-relative theo hàm PHP strtotime.

date_equals:date

Field được validation phải bằng ngày đã cho. Tham số date sẽ được truyền vào hàm strtotime của PHP để được chuyển thành instance DateTime hợp lệ.

date_format:format,...

Field được validation phải khớp với format đã cho. Bạn nên sử dụng một trong hai date hoặc date_format khi validate một field, không dùng cả hai. Quy tắc validation này hỗ trợ tất cả các định dạng mà được hỗ trợ bởi class DateTime của PHP.

Để thuận tiện, các quy tắc dựa trên date có thể được xây dựng bằng cách sử dụng builder rule date:

use Illuminate\Validation\Rule;

'start_date' => [
    'required',
    Rule::date()->format('Y-m-d'),
],

decimal:min,max

Field được validation phải là số và phải có số chữ số thập phân được chỉ định:

// Must have exactly two decimal places (9.99)...
'price' => 'decimal:2'

// Must have between 2 and 4 decimal places...
'price' => 'decimal:2,4'

declined

Field được validation phải là "no", "off", 0, "0", false, hoặc "false".

declined_if:anotherfield,value,...

Field đang được validation phải là "no", "off", 0, "0", false, hoặc "false" nếu một field khác đang được validation bằng một giá trị được nhất định.

different:field

Field được validation phải có giá trị khác với field.

digits:value

Số được validation phải có độ dài chính xác là value.

digits_between:min,max

Số được validation phải có độ dài ở giữa minmax đã cho.

dimensions

File được validation là một image đáp ứng các điều kiện về kích thước hoặc các quy định được tạo bởi các tham số của quy tắc:

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

Các điều kiện có thể được dùng là: min_width, max_width, min_height, max_height, width, height, ratio.

Một điều kiện ratio phải được biểu diễn dưới dạng chiều rộng chia cho chiều cao. Điều này có thể được quy định bằng một phân số như 3/2 hoặc nếu float là 1.5:

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

Vì quy tắc này yêu cầu một số tham số, nên nó thuận tiện hơn khi sử dụng phương thức Rule::dimensions để dễ dàng xây dựng các quy tắc:

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

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

distinct

Khi validation mảng, field được validation phải không được có bất kỳ giá trị trùng lặp nào:

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

Mặc định, Distinct sẽ sử dụng các phép so sánh biến "lỏng lẻo". Để sử dụng so sánh "nghiêm ngặt", bạn có thể thêm tham số strict vào định nghĩa quy tắc validation của bạn:

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

Bạn có thể thêm ignore_case vào các tham số của quy tắc validation để làm cho quy tắc bỏ qua các khác biệt về cách viết hoa:

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

doesnt_start_with:foo,bar,...

Field được validation không được bắt đầu bằng một trong các giá trị đã cho.

doesnt_end_with:foo,bar,...

Field được validation không được kết thúc bằng một trong các giá trị đã cho.

email

Field được validation phải ở định dạng một địa chỉ email. Quy tắc validation này sử dụng package egulias/email-validator để validation. Mặc định, validation RFCValidation sẽ được áp dụng, nhưng bạn cũng có thể áp dụng các kiểu validation khác:

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

Ví dụ trên sẽ áp dụng validation RFCValidationDNSCheckValidation. Dưới đây là một danh sách đầy đủ gồm các kiểu validation mà bạn có thể áp dụng:

  • rfc: RFCValidation - Kiểm tra địa chỉ email theo các RFC đã được hỗ trợ.
  • strict: NoRFCWarningsValidation - Kiểm tra địa chỉ email theo các RFC đã được hỗ trợ, sẽ thất bại nếu tìm thấy cảnh báo (ví dụ: không chấp nhận các dấu chấm ở cuối và nhiều dấu chấm liên tiếp).
  • dns: DNSCheckValidation - Đảm bảo domain của địa chỉ email phải có record MX hợp lệ.
  • spoof: SpoofCheckValidation - Đảm bảo địa chỉ email không chứa các ký tự Unicode lừa đảo hoặc các ký tự đồng hình.
  • filter: FilterEmailValidation - Đảm bảo địa chỉ email hợp lệ theo hàm filter_var của PHP.
  • filter_unicode: FilterEmailValidation::unicode() - Đảm bảo địa chỉ email hợp lệ theo hàm filter_var của PHP và cho phép một số ký tự Unicode.

Để thuận tiện, các quy tắc validation email có thể được xây dựng bằng cách sử dụng builder rule:

use Illuminate\Validation\Rule;

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

[!WARNING] Validator dnsspoof sẽ yêu cầu extension intl của PHP.

encoding:encoding_type

Field được validation phải giống với mã encoding được chỉ định. Rule này sử dụng hàm mb_check_encoding của PHP để xác minh mã encoding của file hoặc giá trị chuỗi đã cho. Để thuận tiện, rule encoding có thể được xây dựng bằng cách dùng builder File rule của Laravel:

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,...

Field được validation phải kết thúc bằng một trong các giá trị đã cho.

enum

Quy tắc Enum là quy tắc dựa trên class nhằm validate xem field đang được validation có chứa giá trị enum hợp lệ hay không. Quy tắc Enum sẽ chấp nhận tên của enum làm tham số khởi tạo duy nhất của nó. Khi kiểm tra các giá trị nguyên thủy như kiểu chuỗi hoặc kiểu số, thì một backed Enum phải được cung cấp cho quy tắc Enum:

use App\Enums\ServerStatus;
use Illuminate\Validation\Rule;

$request->validate([
    'status' => [Rule::enum(ServerStatus::class)],
]);

Các phương thức onlyexcept của quy tắc Enum có thể được sử dụng để giới hạn các trường hợp enum nào được coi là hợp lệ:

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

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

Phương thức when có thể được sử dụng để thêm điều kiện cho quy tắc 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

Field được validation sẽ bị loại ra khỏi dữ liệu request được trả về bởi các phương thức validatevalidated.

exclude_if:anotherfield,value

Field được validation sẽ bị loại trừ khỏi dữ liệu request được trả về từ phương thức validatevalidated nếu một field khác có giá trị bằng giá trị value.

Nếu cần một logic loại trừ có điều kiện phức tạp, bạn có thể sử dụng phương thức Rule::excludeIf. Phương thức này sẽ chấp nhận một giá trị boolean hoặc một closure. Khi được cung cấp closure, closure sẽ trả về true hoặc false để chỉ ra liệu field đang validation có bị loại trừ hay không:

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

Field được validation sẽ bị loại ra khỏi dữ liệu request được trả về từ phương thức validatevalidated trừ khi một field khác có giá trị bằng giá trị value. Nếu valuenull (exclude_unless:name,null), thì field được validation sẽ bị loại ra trừ khi field so sánh là null hoặc field so sánh không tồn tại trong dữ liệu request.

Nếu cần logic loại bỏ có điều kiện phức tạp hơn, bạn có thể sử dụng phương thức Rule::excludeUnless. Phương thức này chấp nhận một giá trị boolean hoặc một closure. Khi được cung cấp một closure, closure nên trả về giá trị true hoặc false để cho biết liệu field đang được validate có nên không bị loại bỏ hay không:

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

Field được validation sẽ bị loại khỏi dữ liệu request được trả về bởi phương thức validatevalidated nếu field anotherfield có tồn tại.

exclude_without:anotherfield

Field được validation sẽ bị loại ra khỏi dữ liệu request được trả về bởi các phương thức validatevalidated nếu field anotherfield không tồn tại.

exists:table,column

Field được validation phải tồn tại trong một bảng cơ sở dữ liệu nhất định.

Cách sử dụng cơ bản của Exists Rule

'state' => 'exists:states'

Nếu tùy chọn column không được chỉ định, thì tên field đó sẽ được sử dụng. Nên, trong trường hợp này, quy tắc sẽ validate rằng bảng cơ sở dữ liệu state sẽ chứa bản ghi có giá trị cột state khớp với giá trị thuộc tính state của request.

Tùy chỉnh tên cột

Bạn có thể chỉ rõ tên cột cơ sở dữ liệu sẽ được sử dụng bởi quy tắc validation bằng cách set nó sau tên bảng cơ sở dữ liệu:

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

Đôi khi, bạn có thể cần chỉ định một kết nối cơ sở dữ liệu cụ thể sẽ được sử dụng cho truy vấn exists. Bạn có thể thực hiện điều này bằng cách thêm tên kết nối vào tên bảng:

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

Thay vì chỉ định trực tiếp tên bảng, bạn có thể chỉ định tên model Eloquent sẽ được sử dụng để xác định tên bảng:

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

Nếu bạn muốn tùy chỉnh truy vấn được thực thi theo quy tắc validation, bạn có thể sử dụng class Rule để dễ dàng định nghĩa các quy tắc. Trong ví dụ này, chúng ta cũng sẽ định nghĩa các quy tắc validation là một mảng thay vì sử dụng ký tự | để phân định chúng:

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

Bạn có thể chỉ định tên cột cơ sở dữ liệu sẽ được sử dụng bởi quy tắc exists được tạo bởi phương thức Rule::exists bằng cách cung cấp tên cột làm tham số thứ hai cho phương thức exists:

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

Thỉnh thoảng, bạn có thể muốn xác thực một mảng giá trị có tồn tại trong database hay không. Bạn có thể làm như vậy bằng cách thêm cả rule exists và rule array vào field đang được validate:

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

Khi cả hai rule này được gán cho một field, Laravel sẽ tự động xây dựng một câu query duy nhất để xác định xem tất cả các giá trị đã cho có tồn tại trong bảng đã chỉ định hay không.

extensions:foo,bar,...

File đang được kiểm tra phải có phần extension tương ứng với một trong các phần extension được liệt kê:

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

[!WARNING] Bạn không nên chỉ dựa vào việc kiểm tra file bằng phần extension. Quy tắc này thường được sử dụng kết hợp với các quy tắc mimes hoặc mimetypes.

file

Field được validation phải là một file được tải lên thành công.

filled

Field được validation phải không được trống khi nó có tồn tại.

gt:field

Field được validation phải lớn hơn field hoặc value. đã cho. Hai field phải cùng loại. Các loại chuỗi, số, mảng và file sẽ được đánh giá bằng cách sử dụng các quy ước giống như quy ước của size.

gte:field

Field được validation phải lớn hơn hoặc bằng field hoặc value. đã cho. Hai field phải cùng loại. Các loại chuỗi, số, mảng và file sẽ được đánh giá bằng cách sử dụng các quy ước giống như quy ước của size.

hex_color

Field được validation phải chứa một giá trị màu hợp lệ ở định dạng hexadecimal.

image

Field được validation phải là một image (jpg, jpeg, png, bmp, gif, hoặc webp).

[!WARNING] Mặc định, rule image không cho phép các file SVG do khả năng xảy ra lỗ hổng bảo mật XSS. Nếu bạn cần cho phép các file SVG, bạn có thể cung cấp tham số allow_svg cho rule image (image:allow_svg).

in:foo,bar,...

Field được validation phải có trong danh sách các giá trị đã cho. Vì quy tắc này thường yêu cầu bạn phải implode một mảng, nên phương thức Rule::in có thể được sử dụng để dễ dàng xây dựng quy tắc:

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

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

Khi quy tắc in được kết hợp với quy tắc array, thì mỗi giá trị có trong mảng input phải có trong danh sách các giá trị được cung cấp cho quy tắc in. Trong ví dụ sau, code airport LAS có trong mảng input sẽ không hợp lệ vì nó không có trong trong danh sách các sân bay được cung cấp cho quy tắc 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.*

Field được validation phải tồn tại trong các giá trị của anotherfield.

in_array_keys:value.*

Field đang được validate phải là một mảng có chứa ít nhất một trong các giá trị values dưới dạng một key có trong mảng:

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

integer

Field được validation phải là một integer.

Bạn có thể dùng thêm tham số strict để chỉ coi field này sẽ là hợp lệ nếu kiểu dữ liệu của nó là integer. Các string mà có chứa giá trị integer cũng sẽ bị coi là không hợp lệ:

'age' => 'integer:strict'

[!WARNING] Quy tắc validation này không xác minh được input thuộc loại biến kiểu "số nguyên", nó chỉ xác minh là input thuộc loại được chấp nhận bởi quy tắc FILTER_VALIDATE_INT của PHP. Nếu bạn cần validate dữ liệu input dưới dạng số, vui lòng sử dụng quy tắc này kết hợp với quy tắc validation numeric.

ip

Field được validation phải là một địa chỉ IP.

ipv4

Field được validation phải là một địa chỉ IPv4.

ipv6

Field được validation phải là một địa chỉ IPv6.

json

Field được validation phải là một chuỗi JSON.

lt:field

Field được validation phải nhỏ hơn field đã cho. Hai field phải cùng loại. Các loại chuỗi, số, mảng và file sẽ được đánh giá bằng cách sử dụng các quy ước giống như quy ước của size.

lte:field

Field được validation phải nhỏ hơn hoặc bằng field đã cho. Hai field phải cùng loại. Các loại chuỗi, số, mảng và file sẽ được đánh giá bằng cách sử dụng các quy ước giống như quy ước của size.

lowercase

Field được validation phải là chữ thường.

list

Field được validation phải là một mảng ở dạng list. Một mảng được coi là một list nếu các key của nó có chứa các số liên tiếp từ 0 đến count($array) - 1.

mac_address

Field được validation phải là một địa chỉ MAC.

max:value

Field được validation phải nhỏ hơn hoặc bằng maximum của value. Chuỗi, số, mảng và file sẽ được so sánh theo cùng một quy tắc với quy tắc size.

max_digits:value

Số được validation phải có độ dài tối đa là value.

mimetypes:text/plain,...

File được validation phải khớp với một trong các loại MIME đã cho:

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

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

Để xác định loại MIME của file được tải lên, nội dung của file sẽ được đọc và framework sẽ cố gắng đoán loại MIME, nó có thể khác với loại MIME của client cung cấp.

mimes:foo,bar,...

File được validation phải có loại MIME tương ứng với một trong các extension đã được liệt kê:

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

Mặc dù bạn chỉ cần định nghĩa extension của file, nhưng thực ra quy tắc này sẽ validate loại MIME của file bằng cách đọc nội dung của file đó và đoán loại MIME của nó. Một danh sách đầy đủ các loại MIME và các extension tương ứng của chúng có thể được tìm thấy tại vị trí sau:

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

MIME Types và Extensions

Quy tắc kiểm tra này không xác minh sự giống nhau giữa loại MIME và phần extension mà người dùng đã gán cho file. Ví dụ, quy tắc kiểm tra mimes:png sẽ coi file chứa các nội dung PNG hợp lệ là một image PNG hợp lệ, ngay cả khi file đó có tên là photo.txt. Nếu bạn muốn kiểm tra phần extension do người dùng gán cho file, bạn có thể sử dụng quy tắc extensions.

min:value

Field được validation phải có value tối thiểu. Chuỗi, số, mảng và file sẽ được so sánh theo cùng một quy tắc với quy tắc size.

min_digits:value

Số được validation phải có độ dài tối thiểu là value.

multiple_of:value

File được validation phải là bội số của value.

missing

File được validation không được tồn tại trong input data.

missing_if:anotherfield,value,...

File được validation không được tồn tại nếu trường anotherfield bằng value.

missing_unless:anotherfield,value

File được validation không được tồn tại trừ khi trường anotherfield bằng value.

missing_with:foo,bar,...

File được validation không được tồn tại chỉ khi có bất kỳ field nào khác được chỉ định tồn tại.

missing_with_all:foo,bar,...

File được validation không được tồn tại chỉ khi tất cả các field khác được chỉ định đều tồn tại.

not_in:foo,bar,...

Field được validation không được chứa trong một danh sách giá trị đã cho. Phương thức Rule::notIn có thể được sử dụng để dễ dàng xây dựng quy tắc:

use Illuminate\Validation\Rule;

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

not_regex:pattern

Field được validation phải không được khớp với biểu thức chính quy đã cho.

Quy tắc này sử dụng hàm preg_match trong PHP. Biểu thức được chỉ định phải tuân theo một định dạng được yêu cầu bởi preg_match và do đó, nó cũng chứa các dấu phân cách. Ví dụ: 'email' => 'not_regex:/^.+$/i'.

[!WARNING] Khi sử dụng mẫu regex hoặc not_regex, có thể cần phải khai báo các quy tắc validation của bạn trong một mảng thay vì sử dụng các dấu | để phân cách, đặc biệt nếu biểu thức chính quy của bạn cũng có chứa ký tự | này.

nullable

Field được validation có thể là null.

numeric

Field được validation phải là numeric.

Bạn có thể dùng thêm tham số strict để chỉ coi field này sẽ là hợp lệ nếu kiểu dữ liệu của nó là integer hoặc float. Các string numeric cũng sẽ bị coi là không hợp lệ:

'amount' => 'numeric:strict'

present

Field được validation phải có tồn tại trong dữ liệu input.

present_if:anotherfield,value,...

Field được validation phải tồn tại nếu field anotherfield bằng bất kỳ value nào.

present_unless:anotherfield,value

Field được validation phải tồn tại nếu field anotherfield không phải bất kỳ value nào.

present_with:foo,bar,...

Field được validation phải tồn tại chỉ khi có bất kỳ field nào khác tồn tại.

present_with_all:foo,bar,...

Field được validation phải tồn tại chỉ khi tất cả các field khác đều tồn tại.

prohibited

Field được validation phải không tồn tại hoặc trống. Một field được coi là "trống" nếu nó đáp ứng một trong các tiêu chí sau:

  • Giá trị là null.
  • Giá trị là một chuỗi rỗng.
  • Giá trị là một mảng rỗng hoặc đối tượng Countable rỗng.
  • Giá trị là một file upload lên có đường dẫn rỗng.

prohibited_if:anotherfield,value,...

Field được validation phải không tồn tại hoặc trống nếu trường anotherfield bằng với value. Một field được coi là "trống" nếu nó đáp ứng một trong các tiêu chí sau:

  • Giá trị là null.
  • Giá trị là một chuỗi rỗng.
  • Giá trị là một mảng rỗng hoặc đối tượng Countable rỗng.
  • Giá trị là một file upload lên có đường dẫn rỗng.

Nếu cần một logic cấm có điều kiện phức tạp, bạn có thể sử dụng phương thức Rule::prohibitedIf. Phương thức này sẽ chấp nhận một giá trị boolean hoặc một closure. Khi được cung cấp closure, closure sẽ trả về true hoặc false để chỉ ra liệu field đang validation có bị cấm hay không:

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,...

Field đang được validate phải bị thiếu hoặc bị trống nếu field anotherfield có giá trị bằng "yes", "on", 1, "1", true, hoặc "true".

prohibited_if_declined:anotherfield,...

Field đang được validate phải bị thiếu hoặc bị trống nếu field anotherfield có giá trị bằng "no", "off", 0, "0", false, hoặc "false".

prohibited_unless:anotherfield,value,...

Field được validation phải thiếu hoặc trống trừ khi field anotherfield bằng value. Một field được coi là "trống" nếu nó đáp ứng một trong các tiêu chí sau:

  • Giá trị là null.
  • Giá trị là một chuỗi rỗng.
  • Giá trị là một mảng rỗng hoặc đối tượng Countable rỗng.
  • Giá trị là một file upload lên có đường dẫn rỗng.

Nếu cần validation cấm có điều kiện phức tạp, bạn có thể sử dụng hàm Rule::prohibitedUnless. Hàm này chấp nhận boolean hoặc closure. Khi truyền vào một closure, closure đó nên trả về giá trị true hoặc false để cho biết liệu trường đang validate có không bị cấm hay không:

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,...

Nếu field đang được validation tồn tại hoặc trống, thì tất cả các field trong anotherfield phải không tồn tại hoặc bị trống. Một field được coi là "trống" nếu nó đáp ứng một trong các tiêu chí sau:

  • Giá trị là null.
  • Giá trị là một chuỗi rỗng.
  • Giá trị là một mảng rỗng hoặc đối tượng Countable rỗng.
  • Giá trị là một file upload lên có đường dẫn rỗng.

regex:pattern

Field được validation phải phù hợp với biểu thức chính quy định.

Quy tắc này sử dụng hàm preg_match trong PHP. Biểu thức được chỉ định phải tuân theo một định dạng được yêu cầu bởi preg_match và do đó, nó cũng chứa các dấu phân cách. Ví dụ: 'email' => 'regex:/^.+@.+$/i'.

[!WARNING] Khi sử dụng quy tắc regex hoặc not_regex, có thể bạn cần phải khai báo các quy tắc đó vào trong một mảng thay vì sử dụng các dấu | để phân cách, đặc biệt nếu biểu thức chính quy của bạn có chứa ký tự |.

required

Field được validation phải có tồn tại trong dữ liệu input và không được trống. Một field là "trống" nếu nó đáp ứng được một trong những tiêu chí sau:

  • Giá trị là null.
  • Giá trị là chuỗi trống.
  • Giá trị là một mảng rỗng hoặc có Countable của object là trống.
  • Giá trị là một file được upload nhưng không có path.

required_if:anotherfield,value,...

Field được validation phải có tồn tại và không được trống nếu trường anotherfield bằng với giá trị value.

Nếu bạn muốn tạo một điều kiện phức tạp hơn cho quy tắc required_if, thì bạn có thể sử dụng phương thức Rule::requiredIf. Phương thức này chấp nhận một boolean hoặc một closure. Khi bạn truyền vào một closure, thì closure này sẽ trả về một giá trị true hoặc false để xem field đang được validation có bắt buộc hay không:

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,...

Field được validation phải tồn tại và không được trống nếu field anotherfield bằng "yes", "on", 1, "1", true hoặc "true".

required_if_declined:anotherfield,...

Field được validation phải tồn tại và không được trống nếu field anotherfield bằng "no", "off", 0, "0", false hoặc "false".

required_unless:anotherfield,value,...

Field được validation phải có tồn tại và không được trống khi trường anotherfield không bằng với giá trị value. Điều này cũng có nghĩa là anotherfield phải có trong dữ liệu request trừ khi valuenull. Nếu valuenull (required_unless:name,null), thì field được validation phải có trừ khi field so sánh là null hoặc field so sánh không tồn tại trong dữ liệu request.

Nếu bạn muốn xây dựng một điều kiện phức tạp hơn cho rule required_unless, bạn có thể sử dụng phương thức Rule::requiredUnless. Phương thức này chấp nhận một biến boolean hoặc một closure. Khi truyền một closure, closure đó nên trả về giá trị true hoặc false để cho biết field đang được validate có không bắt buộc hay không:

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,...

Field được validation phải có tồn tại và không được trống chỉ khi một trong các field khác được khai báo có tồn tại và không rỗng.

required_with_all:foo,bar,...

Field được validation phải có tồn tại và không được trống chỉ khi tất cả các field khác được khai báo đều có tồn tại và không rỗng.

required_without:foo,bar,...

Field được validation phải có tồn tại và không được trống chỉ khi một trong các field khác được khai báo bị trống hoặc không tồn tại.

required_without_all:foo,bar,...

Field được validation phải có tồn tại và không được trống chỉ khi tất cả các field khác được khai báo đều bị trống hoặc không tồn tại.

required_array_keys:foo,bar,...

Field được validation phải là một mảng và phải chứa ít nhất một khóa được chỉ định.

same:field

field đã cho phải match với field được validation.

size:value

Field được validation phải có kích thước khớp với value đã cho. Đối với dữ liệu chuỗi, value tương ứng với số lượng ký tự. Đối với dữ liệu số, value tương ứng với một giá trị số nguyên đã cho (thuộc tính cũng phải có quy tắc numeric hoặc integer). Đối với một mảng, size tương ứng với count của mảng. Đối với file, size tương ứng với kích thước file tính bằng kilobyte. Hãy xem một số ví dụ:

// Validate that a string is exactly 12 characters long...
'title' => 'size:12';

// Validate that a provided integer equals 10...
'seats' => 'integer|size:10';

// Validate that an array has exactly 5 elements...
'tags' => 'array|size:5';

// Validate that an uploaded file is exactly 512 kilobytes...
'image' => 'file|size:512';

starts_with:foo,bar,...

Field được validation phải bắt đầu bằng một trong các giá trị đã cho.

string

Field được validation phải là một chuỗi. Nếu bạn muốn cho phép field được null, thì bạn nên gán quy tắc nullable cho field.

Để giúp thuận tiện hơn cho việc sử dụng, các quy tắc validation string cũng có thể được xây dựng bằng cách sử dụng builder rule Rule::string():

use Illuminate\Validation\Rule;

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

Builder rule string cung cấp các phương thức cho các ràng buộc chuỗi String phổ biến như: alpha, alphaDash, alphaNumeric, ascii, between, doesntEndWith, doesntStartWith, endsWith, exactly, lowercase, max, min, startsWith, và uppercase. Vì builder rule này có khả năng áp dụng điều kiện, nên bạn cũng có thể sử dụng các phương thức whenunless để áp dụng các ràng buộc trên theo một điều kiện nhất định.

timezone

Field được validation phải là một định danh múi giờ hợp lệ theo hàm PHP DateTimeZone::listIdentifiers method.

Các tham số được chấp nhận bởi phương thức DateTimeZone::listIdentifiers cũng có thể được cung cấp cho quy tắc kiểm tra này:

'timezone' => 'required|timezone:all';

'timezone' => 'required|timezone:Africa';

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

unique:table,column

Field được validation phải không tồn tại trong một bảng cơ sở dữ liệu.

Khai báo tên table và tên cột

Thay vì chỉ định trực tiếp tên bảng, bạn có thể chỉ định tên model Eloquent sẽ được sử dụng để xác định tên bảng:

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

Tùy chọn column có thể được sử dụng để chỉ định tên cột sẽ được sử dụng trong cơ sở dữ liệu. Nếu tùy chọn column không được chỉ định, thì tên field validation sẽ được sử dụng.

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

Khai báo database connection cụ thể

Đôi khi, bạn có thể cần cài đặt một custom connection cho các truy vấn cơ sở dữ liệu được tạo bởi Validator. TĐể thực hiện điều này, bạn có thể thêm tên connection vào tên bảng:

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

Bỏ qua một ID nhất định:

Đôi khi, bạn có thể muốn bỏ qua một ID nhất định trong khi validation unique. Ví dụ: hãy xem thử màn hình "update profile" bao gồm tên người dùng, địa chỉ email và vị trí. Bạn có thể sẽ muốn kiểm tra rằng địa chỉ email có là unique hay không. Tuy nhiên, nếu người dùng chỉ thay đổi field tên chứ không phải field email, bạn không thể tạo ra lỗi validate vì người dùng đã là chủ sở hữu của địa chỉ email đó.

Để hướng dẫn validator bỏ qua ID của người dùng, chúng ta sẽ sử dụng class Rule để dễ dàng khai báo quy tắc. Trong ví dụ này, chúng ta cũng sẽ khai báo các quy tắc validation là một mảng thay vì sử dụng ký tự | để phân chia các quy tắc:

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

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);

[!WARNING] Bạn đừng bao giờ truyền bất kỳ input nào do người dùng kiểm soát vào trong phương thức ignore. Thay vào đó, bạn chỉ nên truyền một ID duy nhất do hệ thống tạo ra, chẳng hạn như ID hoặc UUID tăng tự động từ một instance model Eloquent. Nếu không, ứng dụng của bạn sẽ dễ bị tấn công bởi SQL injection.

Thay vì truyền giá trị khóa của model cho phương thức ignore, bạn cũng có thể truyền toàn bộ instance của model đó cho phương thức. Và Laravel sẽ tự động trích xuất khóa của model đó:

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

Nếu bảng của bạn sử dụng tên cột khóa chính khác với id, bạn có thể chỉ định tên của cột khi gọi phương thức ignore:

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

Mặc định, quy tắc unique sẽ kiểm tra tính duy nhất của cột mà khớp với tên của thuộc tính đang được validation. Tuy nhiên, bạn có thể truyền tên một cột khác làm tham số thứ hai cho phương thức unique:

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

Thêm điều kiện where:

Bạn có thể khai báo thêm các điều kiện truy vấn bằng cách sử dụng câu lệnh truy vấn thông qua phương thức where. Ví dụ: hãy thêm một điều kiện truy vấn đưa ra phạm vi truy vấn là chỉ tìm kiếm các bản ghi có giá trị cột account_id1:

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

Ignoring Soft Deleted Records in Unique Checks:

Mặc định, quy tắc unique sẽ chứa cả các record đã bị soft delete khi xác định tính duy nhất. Để loại bỏ các record đã bị soft delete ra khỏi việc kiểm tra tính duy nhất, bạn có thể gọi phương thức withoutTrashed:

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

Nếu model của bạn sử dụng tên cột khác với tên cột deleted_at cho các record đã bị soft delete, bạn có thể cung cấp tên cột đó khi gọi phương thức withoutTrashed:

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

uppercase

Field được validation phải viết hoa.

url

Field được validation phải là một URL hợp lệ.

Nếu bạn muốn chỉ định các giao thức URL sẽ được coi là hợp lệ, bạn có thể truyền các giao thức này dưới dạng tham số quy tắc kiểm tra:

'url' => 'url:http,https',

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

ulid

Field được validation phải là mã định danh duy nhất toàn cầu có thể sắp xếp được (ULID) hợp lệ.

uuid

Field được validation phải là một mã định danh (UUID) RFC 9562 (phiên bản 1, 3, 4, 5, 6, 7, hoặc 8).

Bạn cũng có thể kiểm tra UUID đã cho phải giống với đặc tả của UUID và phiên bản của chúng:

'uuid' => 'uuid:4'

Thêm điều kiện cho Rule

Skipping Validation When Fields Have Certain Values

Đôi khi bạn có thể muốn không kiểm tra một trường nhất định nếu một trường khác có giá trị đã cho. Bạn có thể thực hiện điều này bằng cách sử dụng quy tắc validation exclude_if. Trong ví dụ này, các trường appointment_datedoctor_name sẽ không bị kiểm tra nếu trường has_appointment có giá trị là 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',
]);

Ngoài ra, bạn có thể sử dụng quy tắc exclude_unless để không kiểm tra một trường nhất định trừ khi một trường khác có một giá trị đã cho:

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

Validate khi tồn tại

Trong một số trường hợp, bạn có thể muốn chạy kiểm tra validation đối với một field chỉ khi field đó có trong dữ liệu được validate. Để nhanh chóng thực hiện điều này, hãy thêm quy tắc sometimes vào danh sách quy tắc của bạn:

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

Trong ví dụ trên, field email sẽ chỉ được validate nếu nó có trong mảng $data.

[!NOTE] Nếu bạn đang validate một field luôn luôn tồn tại nhưng có thể trống, hãy xem ghi chú này trên các field tùy chọn.

Validation các điều kiện phức tạp

Thỉnh thoảng bạn có thể muốn thêm các quy tắc validation dựa trên logic điều kiện phức tạp hơn. Ví dụ: bạn muốn bắt buộc nhập một field nếu một field khác có giá trị lớn hơn 100. Hoặc, bạn có thể cần hai field có giá trị mặc định, khi một field khác có tồn tại. Thêm các quy tắc validation này không phải là một điều khó. Đầu tiên, tạo một instance Validator với static rules không bao giờ thay đổi:

use Illuminate\Support\Facades\Validator;

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

Giả sử application web của chúng ta là dành cho người sưu tầm trò chơi. Nếu một nhà sưu tập trò chơi đăng ký với application của chúng ta và họ sở hữu hơn 100 trò chơi, chúng ta muốn họ giải thích lý do tại sao họ sở hữu nhiều trò chơi như vậy. Ví dụ, có thể họ điều hành một cửa hàng bán lại trò chơi, hoặc có thể họ chỉ thích thu thập trò chơi. Để có thêm điều kiện cho các yêu cầu này, chúng ta có thể sử dụng phương thức sometimes trên instance Validator.

use Illuminate\Support\Fluent;

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

Tham số đầu tiên được truyền cho phương thức sometimes là tên của field mà chúng ta đang validate. Tham số thứ hai là một danh sách các quy tắc mà chúng ta muốn thêm. Và nếu closure được truyền làm tham số thứ ba trả về true, thì quy tắc mới được valdiate. Phương thức này làm cho nó dễ dàng để xây dựng các validate có điều kiện phức tạp. Bạn thậm chí có thể thêm các validate có điều kiện cho một số field cùng một lúc:

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

[!NOTE] Tham số $input được truyền cho closure của bạn sẽ là một instance của Illuminate\Support\Fluent và có thể được sử dụng để truy cập vào input hoặc field validation của bạn.

Complex Conditional Array Validation

Thỉnh thoảng bạn có thể muốn validate một field dựa trên một field khác có trong cùng một mảng lồng nhau và số thứ tự của field đó bạn không biết. Trong những tình huống này, bạn có thể cho phép closure của bạn nhận tham số thứ hai sẽ là một item có trong mảng đang được validate:

$input = [
    'channels' => [
        [
            'type' => 'email',
            'address' => '[email protected]',
        ],
        [
            'type' => 'url',
            'address' => 'https://example.com',
        ],
    ],
];

$validator->sometimes('channels.*.address', 'email', function (Fluent $input, Fluent $item) {
    return $item->type === 'email';
});

$validator->sometimes('channels.*.address', 'url', function (Fluent $input, Fluent $item) {
    return $item->type !== 'email';
});

Giống như tham số $input được truyền cho closure, tham số $item là một instance của Illuminate\Support\Fluent khi dữ liệu là một mảng; còn nếu không phải là một mảng thì nó là một chuỗi string.

Validating mảng

Như đã thảo luận trong tài liệu về quy tắc validation array, quy tắc array sẽ chấp nhận một danh sách các khóa được phép có trong mảng. Nếu có thêm bất kỳ khóa nào có trong mảng, thì việc xác thực sẽ bị thất bại:

use Illuminate\Support\Facades\Validator;

$input = [
    'user' => [
        'name' => 'Taylor Otwell',
        'username' => 'taylorotwell',
        'admin' => true,
    ],
];

Validator::make($input, [
    'user' => 'array:name,username',
]);

Nói chung, bạn phải luôn chỉ định các khóa trong mảng được phép có mặt trong mảng của bạn. Nếu không có, các phương thức validatevalidated của validator sẽ trả về tất cả dữ liệu đã validate, bao gồm cả mảng và tất cả các key của nó, thậm chí nếu các khóa đó không được validate bởi các quy tắc validation mảng lồng nhau khác.

Validating Input mảng lồng nhau

Validate một mảng lồng nhau trên các field từ một form input không phải là một vấn đề khó khăn. Bạn có thể sử dụng "ký hiệu chấm" để validate các thuộc tính có trong một mảng. Ví dụ: nếu request HTTP chứa một field photos[profile], bạn có thể validate nó như sau:

use Illuminate\Support\Facades\Validator;

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

Bạn cũng có thể validate từng phần tử trong một mảng. Ví dụ: để validate rằng mỗi email có trong mảng input field đã cho là duy nhất, bạn có thể làm như sau:

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

Tương tự, bạn có thể sử dụng ký tự * khi định nghĩa các tùy chỉnh thông báo validation trong các file language của bạn, giúp dễ dàng sử dụng một thông báo validation duy nhất cho mảng dựa trên các field:

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

Accessing Nested Array Data

Thỉnh thoảng bạn có thể cần truy cập giá trị của một phần tử mảng lồng nhau nhất định khi gán các quy tắc validation cho thuộc tính. Bạn có thể thực hiện việc này bằng phương thức Rule::forEach. Phương thức forEach sẽ chấp nhận một closure sẽ được gọi cho mỗi lần lặp của thuộc tính mảng đang được validation và sẽ nhận vào giá trị của thuộc tính và tên thuộc tính được fully-expanded, rõ ràng. Closure sẽ trả về một mảng các quy tắc để gán cho phần tử mảng:

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

Error Message Indexes và Positions

Khi kiểm tra một mảng, bạn có thể muốn tham chiếu đến giá trị index hoặc vị trí của một item cụ thể bị validation lỗi trong thông báo lỗi do ứng dụng của bạn hiển thị. Để thực hiện việc này, bạn có thể thêm các biến :index (bắt đầu từ 0), :position (starts from 1), or :ordinal-position (starts from 1st) trong thông báo validation tùy biến:

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

Với ví dụ trên, validation sẽ bị thất bại và người dùng sẽ thấy lỗi sau "Please describe photo #2."

Nếu cần, bạn có thể tham chiếu đến các index và vị trí lồng nhau sâu hơn thông qua second-index, second-position, third-index, third-position...

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

Validating Files

Laravel cung cấp nhiều quy tắc validation có thể được sử dụng để validate các file upload, chẳng hạn như mimes, image, minmax. Mặc dù bạn có thể tự do chỉ định các quy tắc này riêng rẽ khi validate file, nhưng Laravel cũng cung cấp một validation rule builder dễ dàng mà bạn có thể thấy tiện lợi:

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

Validator::validate($input, [
    'attachment' => [
        'required',
        File::types(['mp3', 'wav'])
            ->min(1024)
            ->max(12 * 1024),
    ],
]);

Validating File Types

Mặc dù bạn chỉ cần chỉ định các extension khi gọi phương thức types, phương thức này thực sự validate MIME type của file bằng cách đọc nội dung của file và đoán MIME type của nó. Danh sách đầy đủ các MIME type và các extension tương ứng của chúng, bạn có thể tìm thấy tại vị trí sau:

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

Validating File Sizes

Để thuận tiện, kích thước file tối thiểu và tối đa có thể được chỉ định dưới dạng một chuỗi với hậu tố cho biết đơn vị kích thước của file. Các hậu tố được hỗ trợ là kb, mb, gbtb:

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

Validating Image Files

Nếu ứng dụng của bạn chấp nhận image được tải lên từ người dùng, bạn có thể sử dụng method constructor image của rule File để đảm bảo file đang được validate phải là một image (jpg, jpeg, png, bmp, gif, hoặc webp).

Ngoài ra, rule dimensions có thể được sử dụng để giới hạn kích thước của image:

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] Bạn có thể tìm thấy thêm thông tin về việc kiểm tra kích thước image trong tài liệu về rule dimension.

[!WARNING] Mặc định, rule image không cho phép các file SVG do khả năng xảy ra lỗ hổng bảo mật XSS. Nếu bạn cần cho phép các file SVG, bạn có thể truyền allowSvg: true cho rule image: File::image(allowSvg: true).

Validating Image Dimensions

Bạn cũng có thể validate kích thước của một hình ảnh. Ví dụ: để validate một hình ảnh được upload lên có chiều rộng tối thiểu là 1000 pixel và chiều cao tối thiểu là 500 pixel, bạn có thể sử dụng quy tắc dimensions sau:

use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;

File::image()->dimensions(
    Rule::dimensions()
        ->maxWidth(1000)
        ->maxHeight(500)
)

[!NOTE] Thông tin thêm về việc validate kích thước hình ảnh có thể được tìm thấy trong tài liệu quy tắc dimension.

Validating Passwords

Để đảm bảo mật khẩu có mức độ phức tạp phù hợp, bạn có thể sử dụng đối tượng quy tắc Password của Laravel:

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

$validator = Validator::make($request->all(), [
    'password' => ['required', 'confirmed', Password::min(8)],
]);

Đối tượng quy tắc Password cho phép bạn dễ dàng tùy chỉnh các yêu cầu về độ phức tạp của mật khẩu cho ứng dụng của bạn, chẳng hạn như chỉ định rằng mật khẩu sẽ yêu cầu ít nhất một chữ cái, một số, một ký hiệu hoặc một ký tự có kiểu viết hoa hỗn hợp:

// Require at least 8 characters...
Password::min(8)

// Require at least one letter...
Password::min(8)->letters()

// Require at least one uppercase and one lowercase letter...
Password::min(8)->mixedCase()

// Require at least one number...
Password::min(8)->numbers()

// Require at least one symbol...
Password::min(8)->symbols()

Ngoài ra, bạn có thể yêu cầu rằng mật khẩu không bị lộ trong một vụ rò rỉ dữ liệu mật khẩu bằng phương thức uncompromised:

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

Bên trong, đối tượng quy tắc Password sẽ sử dụng model k-Anonymity để xác định xem mật khẩu có bị rò rỉ qua haveibeenpwned.com mà không ảnh hưởng đến quyền riêng tư hoặc bảo mật của người dùng.

Mặc định, nếu một mật khẩu xuất hiện ít nhất một lần trong một vụ rò rỉ dữ liệu thì mật khẩu đó sẽ bị coi là đã bị xâm phạm. Bạn có thể tùy chỉnh ngưỡng này bằng cách sử dụng tham số đầu tiên của phương thức uncompromised:

// Ensure the password appears less than 3 times in the same data leak...
Password::min(8)->uncompromised(3);

Tất nhiên, bạn có thể kết hợp tất cả các phương thức trong các ví dụ trên:

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

Defining Default Password Rules

Bạn có thể thấy thuận tiện khi chỉ định các quy tắc validation mặc định cho tất cả các validation mật khẩu ở một vị trí duy nhất trong ứng dụng của bạn. Bạn có thể dễ dàng thực hiện việc này bằng cách sử dụng phương thức Password::defaults, phương thức này chấp nhận một closure. Closure của phương thức defaults sẽ trả về cấu hình mặc định của quy tắc Password. Thông thường, quy tắc defaults phải được gọi trong phương thức boot của một trong các service provider cho ứng dụng của bạn:

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;
    });
}

Sau đó, khi bạn muốn áp dụng các quy tắc mặc định cho một mật khẩu cụ thể đang được validation, bạn có thể gọi phương thức defaults mà không cần tham số:

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

Đôi khi, bạn có thể muốn đính kèm thêm các quy tắc validation vào các quy tắc validation mật khẩu mặc định của bạn. Bạn có thể sử dụng phương thức rules để thực hiện điều này:

use App\Rules\ZxcvbnRule;

Password::defaults(function () {
    $rule = Password::min(8)->rules([new ZxcvbnRule]);

    // ...
});

Tùy biến Validation Rules

Dùng đối tượng Rule

Laravel cung cấp một loạt các quy tắc validation hữu ích; tuy nhiên, bạn có thể muốn khai báo thêm một số quy tắc của riêng bạn. Một phương thức đăng ký custom validation rule là sử dụng các đối tượng rule. Để tạo một đối tượng rule mới, bạn có thể sử dụng lệnh Artisan make:rule. Hãy sử dụng lệnh này để tạo rule xác minh chuỗi là chữ hoa. Laravel sẽ tạo rule mới trong thư mục app/Rules. Nếu thư mục này không tồn tại, thì Laravel sẽ tạo ra nó khi bạn chạy lệnh Artisan để tạo quy tắc của bạn:

php artisan make:rule Uppercase

Khi rule đã được tạo, chúng ta đã sẵn sàng xác định hành vi của nó. Một đối tượng rule sẽ chứa một phương thức duy nhất: validate. Phương thức này sẽ nhận tên thuộc tính, giá trị của nó và một lệnh callback sẽ được gọi khi có lỗi với thông báo lỗi validation:

<?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.');
        }
    }
}

Khi rule đã được định nghĩa xong, bạn có thể gán nó vào một validator bằng cách truyền một instance của đối tượng rule này cùng với các quy tắc validation khác của bạn:

use App\Rules\Uppercase;

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

Translating Validation Messages

Thay vì cung cấp một thông báo lỗi theo đúng nghĩa đen cho closure $fail, bạn cũng có thể cung cấp khóa dịch và bảo Laravel dịch thông báo lỗi đó:

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

Nếu cần, bạn cũng có thể cung cấp các biến và ngôn ngữ ưu tiên làm tham số thứ nhất và thứ hai cho phương thức translate:

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

Accessing Additional Data

Nếu class quy tắc validation tùy chỉnh của bạn cần truy cập vào tất cả dữ liệu khác đang được validation, thì class quy tắc của bạn có thể implement interface Illuminate\Contracts\Validation\DataAwareRule. Interface này yêu cầu class của bạn định nghĩa một phương thức setData. Phương thức này sẽ tự động được Laravel gọi (trước khi tiến hành validation) với tất cả dữ liệu được validation:

<?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;
    }
}

Hoặc, nếu quy tắc validation của bạn yêu cầu quyền truy cập vào instance validator đang thực hiện validation, bạn có thể implement interface 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;
    }
}

Using Closures

Nếu bạn chỉ cần chức năng của quy tắc tùy chỉnh một lần trong suốt ứng dụng của bạn, bạn có thể sử dụng closure thay vì một đối tượng quy tắc. Closure sẽ nhận vào tên của thuộc tính, giá trị của thuộc tính và một callback $fail sẽ được gọi nếu validation thất bại:

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

Rule ẩn

Mặc định, khi một thuộc tính đang được validate không xuất hiện hoặc chứa một chuỗi trống, thì các quy tắc validation thông thường, bao gồm cả các quy tắc tùy chỉnh, sẽ không được chạy. Ví dụ: quy tắc unique sẽ không được chạy đối với một chuỗi trống:

use Illuminate\Support\Facades\Validator;

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

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

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

Để một quy tắc tùy chỉnh chạy ngay cả khi một thuộc tính trống, quy tắc đó phải tưởng tượng rằng thuộc tính là bắt buộc. Để nhanh chóng tạo ra một đối tượng quy tắc ẩn mới, bạn có thể sử dụng lệnh Artisan make:rule với tùy chọn --implicit:

php artisan make:rule Uppercase --implicit

[!WARNING] Chỉ quy tắc "ẩn" sẽ ám chỉ rằng thuộc tính này là bắt buộc. Việc nó thực sự validate thuộc tính bị thiếu hay trống hay không là tùy thuộc vào bạn.

Session Error Handling
© 2023 by Logo page doc-vn