+7

Custom Validation Rule Laravel 5.5

Giới thiệu

Laravel 5.5

Như các bạn đã biết Laravel 5.5 mới được released vào 30/8 và là phiên bản LTS (Long Term Support) thứ hai sau phiên bản Laravel 5.1. Sự ra đời này cũng đem theo rất nhiều tính năng cải tiến đáng mong đợi như là:

  1. BelongsToMany của Eloquent thay đổi thứ tự parameters, ứng dụng bảng pivot
  2. Thuộc tính $pivotParent của Eloquent
  3. Thuộc tính $exists của model vẫn là true khi dùng soft delete
  4. Thêm hàm withCount(‘foo as bar_count’) với hỗ trợ alias cho tên field
  5. Định dạng được nội dung exception bằng JSON output
  6. Các hàm của validator chuyển hết thành public thay vị protected
  7. Thêm thư mục routes nằm ngoài cho việc định nghĩa các routes của ứng dụng, trước đây routes nằm trong app/Http/routes.php
  8. Các hàm tiện ích của Request thay đổi hành vi trả kết quả: has(), only(). Bỏ hàm intersect()
  9. Headless Chrome testing: tương thích với Laravel Dusk 2.0.0
  10. Thuộc tính $dispatchesEvents của Eloquent
  11. Hàm request($key) không nhận parameter dạng nested key như foo.bar nữa, thay vào đó dùng hàm $request->input($key)
  12. Truyền biến ra view có thể dùng tên hàm động view($viewName)->withMyVariable($value), ra ngoài view sẽ dùng tên biến là $myVariable
  13. MiddleWare group, tách riêng cho nhiều mục đích sử dụng khác nhau
  14. Có thể custom derectives cho biểu thức if của Blade để viết ngắn hơn
  15. Hỗ trợ render email template ra browser, tương thích cho Mailables ... Và còn một số điểm thay đổi nữa các bạn có thể đọc trong trang chủ của Laravel. Và hôm nay mình xin phép được giới thiệu 1 tính năng mới đó là Custom Validation Rule.

Custom Validation Rule là gì

Laravel cung cấp cho chúng ta một số hàm validate có sẵn như là min, max, required, numeric, after, .... https://laravel.com/docs/5.5/validation#available-validation-rules. Mục đích sinh ra validate rule là để tái sử dụng nhiều lần và sử dụng nó một cách dễ dàng chỉ bằng cách gọi tên như mình vừa liệt kê ở trên. Mặc dù cung cấp nhiều đấy nhưng đôi khi chúng ta vẫn cần phải viết thêm những hàm validate riêng trong ứng dụng của mình. Dưới đây mình xin nêu ra 2 cách custom cho những bạn sử dụng Laravel < 5.5 và Laravel 5.5

Bài toán

Yêu cầu: xác định biến truyền vào phải là bắt buộc và là số chẵn.

Custom Validation Rule với Laravel < 5.5

Bước 1. Tạo Route và Controller Ở bước này, chúng ta sẽ tạo ra 2 route, một cái để get method đưa ra view còn một cái cho post method dùng để submit app/Http/routes.php:

Route::get('getCustom', 'CustomValidateController@getCustom'); //get method
Route::post('postCustom', 'CustomValidateController@postCustom'); //post method

Tiếp đến chúng ta sẽ tạo CustomValidateController và viết đoạn code dưới đây: app/Http/Controllers/CustomValidateController.php:

namespace App\Http\Controllers;
use Illuminate\Http\Request;
class CustomValidateController extends Controller
{
	public function getCustom()
	{
		return view('custom_validate');
	}
	public function postCustom(Request $request)
	{
		$this->validate($request, [
	        'number' => 'required|is_even', //required: bắt buộc, is_even: là số chẵn
	    ]);
		print_r('done');
	}
}

Bước 2. Khai báo Validation Ở bước tiếp theo này, mình sẽ khai báo và viết code validation cho is_even vì nó không được Laravel hỗ trợ. Mình sẽ viết trong file app/Providers/AppServiceProvider.php:

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Validator;
class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Validator::extend('is_even', function($attribute, $value, $parameters, $validator) {
            if(!empty($value) && $value % 2 == 0){ //check biến đó không rỗng và chia hết cho 2
                return true;
            }
                return false;
        });
    }
    public function register()
    {
    }
}

Và bây giờ chúng ta phải đưa ra 1 message thông báo lỗi cho người dùng, bạn nên sử dụng trans và khai báo message trong file resoueces/lang/en/validation.php như dưới đây:

return [
	'is_even' => "The :attribute must be even.",
	'accepted' => 'The :attribute must be accepted.',
	.....
]

Bước 3. Tạo View Bước này để tạo 1 view demo, các bạn chỉ cần copy đoạn code này và chạy là xong

<html lang="en">
<head>
	<title>Custom Validation Rule Laravel 5</title>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >
</head>
<body>
	<nav class="navbar navbar-default">
		<div class="container-fluid">
			<div class="navbar-header">
				<a class="navbar-brand" href="#">Custom Validation Rule Laravel 5</a>
			</div>
		</div>
	</nav>
	<div class="container">
		<form action="{{ action('CustomValidateController@postCustom')}}" class="form-horizontal" method="post">
			@if (count($errors) > 0)
			    <div class="alert alert-danger">
			        <ul>
			            @foreach ($errors->all() as $error)
			                <li>{{ $error }}</li>
			            @endforeach
			        </ul>
			    </div>
			@endif
			<input type="text" name="title" class="form-control" style="width:30%" placeholder="Add Even Number" />
			<br/>
			<button class="btn btn-primary">Save</button>
		</form>
	</div>
</body>
</html>

Custom Validation Rule với Laravel 5.5

Bước 1. Tạo Custom Validation Rule bằng dòng lệnh Bước đầu tiên, Laravel 5.5 hỗ trợ chúng ta tạo custom validation rules bằng dòng lệnh

php artisan make:rule CheckEvenRule

Sau khi chạy thành công lệnh trên, bạn sẽ tìm thấy file CheckEvenRule trong thư mục rules của ứng dụng. Trong file này mình sẽ viết những logic đơn giản đó là nhập vào 1 số chẵn rồi trả về đúng, nếu không thì không làm bất cứ điều gì app/Rules/CheckEvenRule.php

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class CheckEvenRule implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        if($value % 2 == 0){
            return true;
        }
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The :attribute must be even value.';
    }
}

Bước 2. Tạo Route Bước này mình cũng tạo ra 2 routes, một get method và một post method

Route::get("form","FormController@index");
Route::post("form","FormController@store");

Bước 3. Tạo Controller Giờ chúng ta cần tạo ra file FormController để xử lý logic app/Http/Controllers/FormController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Rules\CheckEvenRule;

class FormController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
    	return view('myForm');
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function store()
    {
    	$input = request()->validate([
                'name' => 'required',
                'number' => [
                    'required', 
                    new CheckEvenRule()
                ]
            ]);
    	 dd("You can proceed now...");
    }
}

Bước 4. Tạo View Cuối cùng bạn chỉ cần tạo view để demo resources/views/myForm.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>Laravel 5.5 custom validation rules example</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
	<div class="container">
		<h1>Laravel 5.5 custom validation rules example</h1>
		<form method="POST" action="{{ action('FormController@store') }}">
			{{ csrf_field() }}

			<div class="form-group">
				<label>Name:</label>
				<input type="text" name="name" class="form-control" placeholder="Name">
				@if ($errors->has('name'))
					<span class="text-danger">{{ $errors->first('name') }}</span>
				@endif
			</div>

			<div class="form-group">
				<label>Number:</label>
				<input type="number" name="number" class="form-control" placeholder="Number">
				@if ($errors->has('number'))
					<span class="text-danger">{{ $errors->first('number') }}</span>
				@endif
			</div>

			<div class="form-group">
				<button class="btn btn-success btn-submit">Submit</button>
			</div>

		</form>
	</div>
</body>
</html>

Kết luận

Như 2 ví dụ ở trên, các bạn có thể thấy Laravel 5.5 hỗ trợ việc viết Custom Validation một cách dễ hiểu và trong sáng hơn bằng cách tạo file Rule chứ không phải viết tất cả trong hàm boot() trong AppServiceProvider ở Laravel < 5.5. Việc viết code trở nên clear hơn rất nhiều.

Bài viết của mình xin kết thúc ở đây. Cảm ơn các bạn đã đón đọc!

Tham khảo

  1. https://laravel.com/docs/5.4/validation#custom-validation-rules
  2. https://laravel.com/docs/5.5/validation#custom-validation-rules

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí