Khi người dùng gửi dữ liệu từ form, API hoặc một HTTP request, ứng dụng không nên sử dụng trực tiếp dữ liệu đó mà chưa kiểm tra. Laravel Validation cung cấp hệ thống Validation Rule giúp xác định dữ liệu có đúng định dạng, kiểu dữ liệu và điều kiện nghiệp vụ cơ bản hay không. Laravel hỗ trợ nhiều cách validation khác nhau, từ kiểm tra trực tiếp trong Controller đến sử dụng Form Request để tách riêng logic xác thực dữ liệu.
Laravel Validation là gì?
Laravel Validation là cơ chế kiểm tra dữ liệu đầu vào của Laravel dựa trên một tập hợp các Validation Rule.
Ví dụ, một form đăng ký có thể yêu cầu:
- Tên không được để trống.
- Email phải đúng định dạng.
- Mật khẩu có độ dài tối thiểu.
- Email không được trùng trong database.
Có thể mô tả quy trình:
Người dùng nhập dữ liệu
↓
HTTP Request
↓
Laravel Validation
↓
Dữ liệu hợp lệ?
↙ ↘
Có Không
↓ ↓
Xử lý tiếp Trả lỗi
Validation giúp ứng dụng kiểm soát dữ liệu trước khi đưa vào các bước xử lý tiếp theo.
Vì sao cần Validation?
Dữ liệu gửi từ client không nên được mặc định là chính xác.
Ví dụ một form yêu cầu tuổi: age = abc
Trong khi ứng dụng mong muốn: age = 25
Nếu không kiểm tra, dữ liệu sai có thể gây lỗi ở các bước tiếp theo.
Validation giúp:
- Kiểm tra dữ liệu bắt buộc.
- Kiểm tra định dạng.
- Kiểm tra kiểu dữ liệu.
- Kiểm tra độ dài.
- Kiểm tra giá trị.
- Kiểm tra tính duy nhất.
- Giảm dữ liệu không hợp lệ đi vào hệ thống.
Validation không thay thế toàn bộ các cơ chế bảo mật khác, nhưng là một lớp kiểm soát quan trọng đối với dữ liệu đầu vào.
Validation trực tiếp trong Controller
Cách đơn giản nhất là sử dụng:
$request->validate()
Ví dụ:
use Illuminate\Http\Request;
public function store(Request $request)
{
$validated = $request->validate([
‘name’ => [‘required’, ‘string’, ‘max:255’],
’email’ => [‘required’, ’email’],
‘age’ => [‘required’, ‘integer’, ‘min:18’],
]);
// Xử lý dữ liệu hợp lệ
}
Ở đây:
- name bắt buộc là chuỗi và tối đa 255 ký tự.
- email bắt buộc và phải có định dạng email.
- age phải là số nguyên và tối thiểu 18.
Sau khi validation thành công, biến $validated chứa dữ liệu đã vượt qua các rule được khai báo.
Các Validation Rule phổ biến
Laravel cung cấp rất nhiều rule. Một số rule thường gặp:
| Rule | Ý nghĩa |
| required | Bắt buộc có giá trị |
| nullable | Cho phép giá trị null |
| string | Phải là chuỗi |
| integer | Phải là số nguyên |
| numeric | Phải là số |
| Kiểm tra định dạng email | |
| boolean | Kiểm tra giá trị boolean |
| array | Phải là mảng |
| date | Phải là ngày hợp lệ |
| url | Kiểm tra URL |
| min | Giá trị hoặc độ dài tối thiểu tùy dữ liệu |
| max | Giá trị hoặc độ dài tối đa tùy dữ liệu |
| in | Giá trị phải nằm trong danh sách |
| unique | Kiểm tra tính duy nhất |
| exists | Kiểm tra giá trị tồn tại trong database |
Ví dụ:
$request->validate([
‘username’ => [‘required’, ‘string’, ‘max:50’],
’email’ => [‘required’, ’email’],
‘age’ => [‘integer’, ‘min:18’],
]);
Kiểm tra dữ liệu duy nhất
Laravel hỗ trợ kiểm tra dữ liệu không được trùng trong database.
Ví dụ: ’email’ => [‘required’, ’email’, ‘unique:users,email’]
Rule này yêu cầu email chưa xuất hiện trong cột email của bảng users. Khi cập nhật user, cần loại trừ bản ghi hiện tại thay vì áp dụng unique một cách máy móc.
Ví dụ có thể sử dụng Rule object:
use Illuminate\Validation\Rule;
’email’ => [
‘required’,
’email’,
Rule::unique(‘users’, ’email’)->ignore($user->id),
],
Điều này giúp tránh trường hợp người dùng giữ nguyên email của chính mình nhưng validation lại báo trùng.
Kiểm tra dữ liệu tồn tại
Rule exists thường được sử dụng khi một giá trị phải tồn tại trong database.
Ví dụ:
‘user_id’ => [
‘required’,
‘integer’,
‘exists:users,id’,
],
Laravel sẽ kiểm tra user_id có tồn tại trong cột id của bảng users hay không.
Rule này hữu ích với:
- ID người dùng.
- ID danh mục.
- ID sản phẩm.
- ID đơn hàng.
- Các khóa ngoại được gửi từ client.
Hiển thị lỗi Validation trong Blade
Khi validation thất bại trong web request, Laravel có thể đưa lỗi trở lại session để View sử dụng.
Trong Blade, có thể kiểm tra lỗi:
@if ($errors->any())
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
Hoặc lấy lỗi của một field:
@error(’email’)
<span>{{ $message }}</span>
@enderror
Cách thứ hai phù hợp khi muốn hiển thị lỗi ngay cạnh input tương ứng.
Validation dữ liệu từ API
Validation không chỉ dành cho HTML form. API cũng cần kiểm tra dữ liệu đầu vào.
Ví dụ:
public function store(Request $request)
{
$validated = $request->validate([
‘title’ => [‘required’, ‘string’, ‘max:255’],
‘content’ => [‘required’, ‘string’],
]);
return response()->json([
‘data’ => $validated,
]);
}
Với API, Laravel có thể trả về phản hồi validation phù hợp để client xử lý. Frontend có thể sử dụng thông tin lỗi để hiển thị cho người dùng.
Validation và chuẩn hóa dữ liệu
Validation chủ yếu trả lời câu hỏi: Dữ liệu có đáp ứng các điều kiện được yêu cầu hay không? Còn chuẩn hóa dữ liệu có thể bao gồm việc chuẩn bị dữ liệu trước khi xử lý.
Ví dụ, với dữ liệu tên:
” Nguyen Van A “
Ứng dụng có thể cần loại bỏ khoảng trắng thừa trước khi lưu.
Trong Form Request, có thể sử dụng prepareForValidation() cho những trường hợp cần chuẩn bị dữ liệu trước khi chạy rules.
Ví dụ:
protected function prepareForValidation(): void
{
$this->merge([
‘name’ => trim($this->name),
]);
}
Tuy nhiên, không nên biến bước này thành nơi xử lý business logic phức tạp.
Custom Validation Rule
Khi các rule có sẵn không đáp ứng yêu cầu, Laravel cho phép tạo Custom Validation Rule.
Ví dụ:
php artisan make:rule StrongPassword
Sau đó tạo logic kiểm tra riêng trong Rule.
Có thể sử dụng:
‘password’ => [
‘required’,
new StrongPassword,
],
Custom Rule phù hợp khi một điều kiện validation:
- Được sử dụng nhiều nơi.
- Có logic riêng.
- Khó biểu diễn bằng các rule có sẵn.
- Cần tách thành một thành phần có thể kiểm thử.
Validation nhiều điều kiện
Không phải dữ liệu nào cũng chỉ có một rule đơn giản.
Ví dụ một field có thể yêu cầu:
‘phone’ => [
‘required’,
‘string’,
‘max:20’,
],
Hoặc sử dụng các Rule object khi điều kiện phức tạp hơn:
use Illuminate\Validation\Rule;
‘status’ => [
‘required’,
Rule::in([‘pending’, ‘approved’, ‘rejected’]),
],
Với những trường hợp có điều kiện phụ thuộc vào dữ liệu khác, Laravel cũng cung cấp nhiều rule có điều kiện để xây dựng validation phù hợp.
Những lỗi thường gặp khi sử dụng Validation
Chỉ kiểm tra ở Frontend
Validation ở JavaScript giúp cải thiện trải nghiệm người dùng nhưng không thay thế validation phía server. Client có thể gửi request trực tiếp mà không thông qua giao diện frontend. Do đó, Laravel vẫn cần kiểm tra dữ liệu ở phía server.
Validation quá sơ sài
Ví dụ:
’email’ => [‘required’]
Rule này chỉ đảm bảo field có giá trị, chưa kiểm tra email có đúng định dạng hay không.
Có thể sử dụng:
’email’ => [‘required’, ’email’]
Đưa quá nhiều logic vào Controller
Controller với hàng chục hoặc hàng trăm dòng validation sẽ khó bảo trì.
Khi rules phức tạp, Form Request là lựa chọn phù hợp hơn.
Nhầm Validation với Security
Validation giúp kiểm soát dữ liệu đầu vào nhưng không phải lớp bảo mật duy nhất.
Ứng dụng vẫn cần quan tâm đến:
- Authentication.
- Authorization.
- CSRF.
- SQL Injection.
- XSS.
- Mass Assignment.
- Phân quyền tài nguyên.
Không nên xem việc thêm validate() là đã giải quyết toàn bộ vấn đề bảo mật.
Kết luận
Laravel Validation là cơ chế quan trọng để kiểm tra dữ liệu trước khi ứng dụng tiếp tục xử lý.
Những điểm cần nhớ:
- Validation kiểm tra dữ liệu đầu vào dựa trên các Rule.
- Laravel cung cấp nhiều rule có sẵn cho string, số, email, database và nhiều loại dữ liệu khác.
- Có thể validation trực tiếp bằng $request->validate().
- Form Request phù hợp với validation phức tạp hoặc cần tách riêng khỏi Controller.
- prepareForValidation() có thể dùng để chuẩn hóa dữ liệu trước khi kiểm tra.
- Custom Rule phù hợp với các điều kiện đặc thù.
- Validation phía server vẫn cần thiết ngay cả khi frontend đã kiểm tra dữ liệu.
- Validation là một lớp kiểm soát dữ liệu, không thay thế toàn bộ cơ chế bảo mật.
Khi sử dụng đúng Validation, dữ liệu đi vào các tầng xử lý phía sau sẽ có cấu trúc và điều kiện rõ ràng hơn, giúp ứng dụng Laravel dễ bảo trì và giảm nhiều lỗi phát sinh từ dữ liệu đầu vào.
