Bài 15: Validation trong Laravel – Học lập trình Laravel

Trang chủ » Training » Bài 15: Validation trong Laravel – Học lập trình Laravel
28/02/2022 Training 18 viewed

1. Giới thiệu

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 ValidateRequests để cung cấp phương thức khá thuận tiện cho việc validate HTTP request với đa dạng quy định Validation

2. Tạo một Validator cơ bản

Để bắt đầu sử dụng các tính năng của Validator 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();
    }
}

3. Form Request Validator

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',
    ];
}
Chia sẻ:
Tags:
TOP HOME