Bỏ qua đến nội dung chính

Laravel validation: các quy tắc phổ biến và cách dùng

Hướng dẫn kiểm tra dữ liệu trong Laravel bản hiện hành: bốn cách validation, bảng quy tắc hay dùng, hiển thị lỗi trong Blade, rule tự viết và Việt hóa thông báo.

Tan Hien
Founder
Cập nhật 6 phút đọc
Chia sẻ:
Laravel validation: các quy tắc phổ biến và cách dùng
Nội dung bài viết
  1. 1.Cách 1: Validate ngay trong controller
  2. 2.Cách 2: Form Request cho form phức tạp
  3. 3.Cách 3: Validator::make khi cần tự xử lý
  4. 4.Các quy tắc validation hay dùng
  5. 5.Hiển thị lỗi và giữ lại dữ liệu cũ trong Blade
  6. 6.Viết quy tắc validation riêng
  7. 7.Việt hóa thông báo lỗi
  8. 8.Validation trong Livewire
  9. 8.1Kinh nghiệm từ Hozitech

Validation trong Laravel là bước kiểm tra dữ liệu người dùng gửi lên (form, API) theo các quy tắc như required, email, max:255, unique trước khi lưu. Cách nhanh nhất là gọi $request->validate([...]) trong controller; form lớn nên dùng Form Request. Khi dữ liệu không hợp lệ, Laravel tự quay lại trang trước kèm thông báo lỗi và dữ liệu cũ.

Bài viết đi qua bốn cách validation, các quy tắc hay dùng, cách hiển thị lỗi, viết rule riêng và Việt hóa thông báo, theo tài liệu Validation của Laravel 13 (truy cập 01/10/2026).

Bảng 4 cách kiểm tra dữ liệu trong Laravel: validate() của request, Form Request, Validator::make và rule tự viết
Chọn cách validation theo độ phức tạp của form.

Cách 1: Validate ngay trong controller

Phương thức validate của request nhận mảng quy tắc. Nếu hợp lệ, nó trả về mảng dữ liệu đã kiểm tra; nếu không, Laravel ném ngoại lệ và tự chuyển hướng về trang trước (với request thường) hoặc trả JSON lỗi mã 422 (với request API/AJAX).

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

public function store(Request $request): RedirectResponse
{
    $validated = $request->validate([
        'title' => ['required', 'unique:posts', 'max:255'],
        'body'  => ['required'],
    ]);

    Post::create($validated);

    return redirect('/posts');
}

Quy tắc có thể viết dạng mảng (khuyên dùng) hoặc chuỗi nối bằng dấu | như 'required|max:255'.

Cách 2: Form Request cho form phức tạp

Form Request tách toàn bộ quy tắc, phân quyền và thông báo lỗi ra một class riêng, giúp controller gọn và dùng lại được.

php artisan make:request StorePostRequest
# Tạo: app/Http/Requests/StorePostRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    public function rules(): array
    {
        return [
            'title' => ['required', 'string', 'max:255', 'unique:posts'],
            'body'  => ['required', 'string'],
            'publish_at' => ['nullable', 'date', 'after:today'],
        ];
    }

    public function messages(): array
    {
        return [
            'title.required' => 'Vui lòng nhập tiêu đề.',
            'title.unique'   => 'Tiêu đề này đã tồn tại.',
        ];
    }
}

Trong controller chỉ cần khai báo kiểu tham số; Laravel kiểm tra trước khi phương thức chạy:

public function store(StorePostRequest $request): RedirectResponse
{
    Post::create($request->validated());

    return redirect('/posts');
}

Nếu authorize() trả về false, Laravel trả lỗi 403 mà không chạy controller. Xem thêm cách tổ chức controller ở bài controller trong Laravel.

Cách 3: Validator::make khi cần tự xử lý

Dùng facade Validator khi muốn tự quyết định phản hồi lỗi, hoặc khi dữ liệu không đến từ request (file import, lệnh Artisan, job):

use Illuminate\Support\Facades\Validator;

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

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

$validated = $validator->validated();

Lưu ý dùng withErrors() và withInput() (không phải with('error', ...)) để view nhận được biến $errors và hàm old() hoạt động.

Các quy tắc validation hay dùng

Quy tắcÝ nghĩaVí dụ
requiredBắt buộc có và không rỗng'name' => ['required']
nullableCho phép để trống (null)['nullable', 'date']
sometimesChỉ kiểm tra khi trường có trong dữ liệu gửi lên['sometimes', 'required']
bailDừng ở lỗi đầu tiên của trường đó['bail', 'required', 'email']
string, integer, numeric, boolean, arrayKiểu dữ liệu['integer', 'min:1']
min, max, betweenĐộ dài chuỗi, giá trị số, số phần tử mảng hoặc dung lượng file (KB)['string', 'max:255']
email, urlĐúng định dạng email, URL['required', 'email']
unique, existsChưa có / phải có trong bảng database'unique:users,email'
confirmedKhớp với trường ..._confirmationMật khẩu nhập lại
inNằm trong danh sách cho phép'in:draft,published'
date, after, beforeNgày hợp lệ, sau/trước một mốc['date', 'after:today']
image, mimesFile ảnh, đúng định dạng['image', 'mimes:jpg,png', 'max:2048']
regexKhớp biểu thức chính quySố điện thoại 10 chữ số

Khi sửa bản ghi, quy tắc unique cần bỏ qua chính bản ghi đó:

use Illuminate\Validation\Rule;

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

Hiển thị lỗi và giữ lại dữ liệu cũ trong Blade

<form method="POST" action="/posts">
    @csrf
    <input type="text" name="title" value="{{ old('title') }}"
           class="@error('title') is-invalid @enderror">

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

    <button type="submit">Lưu</button>
</form>

Biến $errors luôn có sẵn trong view thuộc nhóm middleware web; có thể liệt kê toàn bộ lỗi bằng $errors->all(). Token @csrf là bắt buộc với form POST, xem bài CSRF trong Laravel.

Viết quy tắc validation riêng

Khi cần quy tắc nghiệp vụ không có sẵn, tạo rule bằng Artisan. Class sinh ra trong app/Rules có một phương thức validate, gọi $fail() khi dữ liệu không đạt:

php artisan make:rule VietnamesePhone
<?php

namespace App\Rules;

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

class VietnamesePhone implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (! preg_match('/^0\d{9}$/', (string) $value)) {
            $fail('Số điện thoại phải gồm 10 chữ số và bắt đầu bằng 0.');
        }
    }
}
use App\Rules\VietnamesePhone;

$request->validate([
    'phone' => ['required', new VietnamesePhone],
]);

Việt hóa thông báo lỗi

Thông báo mặc định của Laravel bằng tiếng Anh. Dự án mới không có sẵn thư mục lang; chạy lệnh dưới để xuất file ngôn ngữ, sau đó tạo lang/vi/validation.php (sao chép từ lang/en/validation.php rồi dịch) và đặt APP_LOCALE=vi trong .env.

php artisan lang:publish
// lang/vi/validation.php (trích)
return [
    'required' => 'Trường :attribute là bắt buộc.',
    'email'    => 'Trường :attribute phải là địa chỉ email hợp lệ.',
    'max'      => [
        'string' => 'Trường :attribute không được dài quá :max ký tự.',
    ],
    'attributes' => [
        'title' => 'tiêu đề',
        'phone' => 'số điện thoại',
    ],
];

Nếu chỉ cần sửa vài thông báo cho một form, dùng phương thức messages() trong Form Request như ở trên.

Validation trong Livewire

Với component Livewire, quy tắc gắn trực tiếp lên thuộc tính bằng attribute #[Validate('required|min:3')] và gọi $this->validate() trong phương thức xử lý; xem ví dụ đầy đủ ở bài Laravel Livewire là gì.

Kinh nghiệm từ Hozitech

Website Hozitech chạy trên Laravel và có nhiều form như liên hệ, đăng ký nhận tin. Với các form công khai, nên kiểm tra phía máy chủ dù đã có kiểm tra bằng JavaScript, vì dữ liệu gửi lên có thể bị sửa ngoài trình duyệt; giới hạn độ dài mọi trường chữ bằng max để tránh dữ liệu rác; và chỉ lưu dữ liệu từ validated() thay vì $request->all(), để các trường không khai báo quy tắc không lọt vào database. Muốn hiểu dữ liệu đi qua những lớp nào trước khi tới bước validation, đọc thêm vòng đời request của Laravel và tổng quan Laravel.

Tan Hien

Về tác giả

Founder

Xin chào mình là Hiền hiện đang là Founder của Hozitech. Mình là kỹ sư phần mềm có hơn 9+ năm kinh nghiệm trong lĩnh vực thiết kế website, ứng dụng di động... Gần đây mình đang nghiên cứu thêm về lĩnh vực marketing. Mình rất vui khi được chia sẽ những kiến thức và kinh nghiệm của mình đến mọi người!

Câu hỏi thường gặp

Câu hỏi thường gặp

Sẵn sàng bắt đầu dự án của bạn?

Hãy để chúng tôi giúp bạn biến ý tưởng thành hiện thực. Đăng ký tư vấn miễn phí ngay hôm nay để nhận được giải pháp công nghệ tối ưu cho doanh nghiệp.