12/08/2018, 14:12

Validation trong Laravel 5.3

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

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 AppHttpControllers;

use IlluminateHttpRequest;
use AppHttpControllersController;

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(AppHttpControllersController) 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 IlluminateSupportMessageBag. 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 IlluminateContractsValidationValidator ở trên đầu file nhé :

namespace AppHttpControllers;

use IlluminateFoundationBusDispatchesJobs;
use IlluminateContractsValidationValidator;
use IlluminateRoutingController as BaseController;
use IlluminateFoundationValidationValidatesRequests;

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 AppHttpRequestsRequest. Đừng quên import class IlluminateContractsValidationValidator 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

https://laravel.com/docs/5.3

0