Validation trong Laravel 5.3
Bài đăng này đã không được cập nhật trong 7 năm
1.Giới Thiệu Khái Quát
Laravel cung cấp một vài cách tiếp cận để Validate dữ liệu đến ứng dụng của bạn. Mặc định Class Base Controller của Laravel sử dụng ValidatesRequests
để cung cấp phương thức khá thuận tiện cho việc validate HTTP requesst với đa dạng quy định Validation.
2.Tạo một Validation cơ bản
Để bắt đầu sử dụng các tính năng của Validation trong Laravel. Chúng ta hãy xem một ví dụ hoàn chỉnh khi Validate một form và hiển thị nội dung lỗi trả về cho người dùng.
Xác định Routes
Đầu tiên, giả sử chúng ta có Route được định nghĩa sẵn trong routes/web.php
:
Route::get('post/create', 'PostController@create');
Route::post('post', 'PostController@store');
Tất nhiên phương thức GET
Route sẽ hiển thị một form cho người dùng tọa mới một bài viết. Trong khi phương thức POST
Route sẽ lưu bài viết đấy vào cơ sở dữ liệu.
Tạo Controller
Tiếp theo chúng ta sẽ tạo một Controller đơn giản để xử lý các routes. Bây giờ chúng ta sẽ để trống function Store:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PostController extends Controller
{
/**
* Show the form to create a new blog post.
*
* @return Response
*/
public function create()
{
return view('post.create');
}
/**
* Store a new blog post.
*
* @ param Request $request
* @ return Response
*/
public function store(Request $request)
{
// Validate and store the blog post...
}
}
Viết code logic Validation
Bây giờ chúng ta sẽ viết code logic vào phương thức store
để validate khi tạo mới một bài viết. Nếu bạn kiểm tra Class Base Controller(App\Http\Controllers\Controller
) của Laravel thì bạn sẽ thấy Class sử dụng một ValidatesRequests
. Nó cung cấp một phương thức validate
cho tất cả các Controllers.
Phương thức validate
chấp nhận một HTTP request đến và đặt quy định Validation. Nếu quy định Validation thành công, code của bạn sẽ thực thi bình thường. Tuy nhiên nếu Validation thất bại thì một Exception sẽ được bắn ra và tích hợp lỗi response sẽ được tự động gửi đến cho người dùng.Trong trường hợp là HTTP request thì một response chuyển trang sẽ được tạo ra trong khi một JSON response sẽ được gửi cho AJAX requests.
Để cho các bạn có thể hiểu rõ hơn về phương thức validate
. hãy xem đoạn code được viết vào function store
:
/**
* Store a new blog post.
*
* @ param Request $request
* @ return Response
*/
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid, store in database...
}
Như các bạn có thể thấy. Chúng ta có thể truyền qua HTTP request đến và yêu cầu quy định Validation vào phương thức validate
. Một lần nữa, nếu Validation thất bại thì một Proper Response sẽ tự động được tạo ra. Nếu Validation thành công thì Controller sẽ được thực thi bình thường.
Dừng khi Validation đầu tiên thất bại
Đôi khi các bạn muốn quy định Validation trong một thuộc tính sau khi Validation đầu tiên thất bại.Để làm được việc đó chúng ta sẽ gán bail
cho thuộc tính
$this->validate($request, [
'title' => 'bail|required|unique:posts|max:255',
'body' => 'required',
]);
Trong ví dụ trên, nếu quy định required
cho thuộc tính title
bị thật bại thì quy định unique
sẽ không cần kiểm tra.Các quy định sẽ được validate theo thứ tự mà nó được gán.
Chú ý về thuộc tính lồng nhau
Nếu HTTP requesst chứa tham số "lồng nhau". Các bạn có thể chỉ định chúng trong quy định Validate bằng cách sử dụng "dấu chấm":
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'author.name' => 'required',
'author.description' => 'required',
]);
Hiển thị Validation lỗi
Điều gì sẽ xảy rakhi có một tham số request gửi đến không thành công theo quy định của Validation?. Như đã đề cập ở trước, Laravel sẽ tự động kiểm tra lồi trong dữ liệu Session và tự động bind chúng vào View nếu chúng tồn tại. Biến $errors
sẽ là một đơn vị của Illuminate\Support\MessageBag
. Vì vậy ở trong ví dụ trên. Người dùng sẽ chuyển đến fuction create
của Controller khi Validation thất bại. Cho phép chúng ta hiển thị nội dung lỗi trên View:
<!-- /resources/views/post/create.blade.php -->
<h1>Create Post</h1>
@ if(count($errors) > 0)
<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 định dạng lỗi Flashed
Giả sử nếu như các bạn muốn tùy chỉnh nội dũng lỗi của Validation được Flashed vào Session khi Validation thất bại, hãy ghi đè phương thức formatValidationErrors
trong Base Controller. Đừng quyên Import Class Illuminate\Contracts\Validation\Validator
ở trên đầu file nhé :
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
abstract class Controller extends BaseController
{
use DispatchesJobs, ValidatesRequests;
/**
* {@inheritdoc}
*/
protected function formatValidationErrors(Validator $validator)
{
return $validator->errors()->all();
}
}
AJAX Requests và Validation
Trong ví dụ trên, chúng ta sử dụng form để gửi dữ liệu vào ứng dụng. Tuy nhiên nhiều ứng dụng sử dụng AJAX requests. Khi sử dụng phương thức validate
trong AJAX request Laravel sẽ không tạo ra redirect respones thay vì Laravel tạo một JSON response chứ tất cả lỗi validation thì JSON response này sẽ được gửi với mã 422 HTTP status.
3.Form Request Validation
Tạo Form Request
Với những trường họp Validation phức tạp thì bạn có thể tạo một "form request".Form requests là tùy chỉnh class request chứa logic Validation. Để tạo class form request ta sử dụng lệnh make:request
.
php artisan make:request StoreBlogPost
Class được tạo sẽ nằm ở thư mục app/Http/Requests
. Nếu như thư mục đó không tồn tại nó sẽ được tạo khi chạy lệnh make:request
. Chúng ta sẽ thêm một vài quy định Validation vào trong function rules
:
/**
* Get the validation rules that apply to the request.
*
* @ return array
*/
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
Form request được Validated trước khi phương thức Controller được gọi. Có nghĩa là bạn không cần viết nhiều logic vào trong Controller.Nếu Validation thất bại, một trang response sẽ được tạo ra để gửi lại cho người dùng quay trở lại trang trước đó.Ngoài ra lỗi sẽ được flashed vào session. Vì vậy chúng ta có thể hiển thị nó nếu request là AJAX request.
Authorizing Form Requests
Class form request ngoài ra còn chứa một function authorize
. Bên trong function này các bạn có thể xác thực người dùng thực sự có quyền cập nhật dữ liệu. Ví dụ, nếu người dùng muốn cập nhật comment trong một bài viết thì bài viết đó phải là của họ.
/**
* Determine if the user is authorized to make this request.
*
* @ return bool
*/
public function authorize()
{
$comment = Comment::find($this->route('comment'));
return $comment && $this->user()->can('update', $comment);
}
Khi tất cả các form requests kế thừ từ Class base Laravel request chúng ta có thể sử dụng function user
để truy cập và xác thực người dùng.Ngoài ra cũng cần gọi đến route
ở trong ví dụ trên. Phương thức này cho phép các bạn truy cập đến tham số của URI được định nghĩa trong route, như tham số {comment}
:
Route::post('comment/{comment}');
Nếu function authorize
trả về false, một HTTP response với mã 403 sẽ tự động trả về và phương thức Controller sẽ không được thực hiện.
Tùy biến định dạng lỗi
Nếu các bạn muốn tùy biến định dạng lỗi Validation được flashed vào session khi Validation thất bại hãy ghi đè function formatErrors
trong base request App\Http\Requests\Request
. Đừng quên import class Illuminate\Contracts\Validation\Validator
lên trên đầu file:
/**
* {@ inheritdoc}
*/
protected function formatErrors(Validator $validator)
{
return $validator->errors()->all();
}
Tùy biến nội dung hiển thị lỗi
Các bạn có thể tùy biến nội dung lỗi bằng cách sử dụng form request và ghi đè lên function messages
. function này trả về một mảng các thuộc tính quy định tương ứng với nội dung lỗi:
/**
* Get the error messages for the defined validation rules.
*
* @ return array
*/
public function messages()
{
return [
'title.required' => 'A title is required',
'body.required' => 'A message is required',
];
}
Dưới đây tôi đã giới thiệu các bước thực hiện một ví dụ cơ bản về Validation trong Laravel 5.3.Cảm ơn các bạn đã theo dõi. Nếu có bất kì thắc mắc gì hãy để lại comment ở phía dưới nhé.
Thao Khảo
All rights reserved