Laravel Form validation – kiểm soát thông tin nhập liệu

Laravel cung cấp rất nhiều cách thức để kiểm tra thông tin nhập trên các form nhập liệu, cách thức mặc định là sử dụng một base controller sử dụng trail ValidatesRequests, nó cung cấp rất nhiều các phương thức kiểm tra thông tin đến từ các HTTP request.

Danh sách các validate rule trong Laravel 5.4

Số lượng các validate rule là rất nhiều, đủ cho chúng ta kiểm tra dữ liệu các dạng thông tin nhập liệu:

Accepted
Active URL
After (Date)
After Or Equal (Date)
Alpha
Alpha Dash
Alpha Numeric
Array
Before (Date)
Before Or Equal (Date)
Between
Boolean
Confirmed
Date
Date Format
Different
Digits
Digits Between
Dimensions (Image Files)
Distinct
E-Mail
Exists (Database)
File
Filled
Image (File)
In
In Array
Integer
IP Address
JSON
Max
MIME Types
MIME Type By File Extension
Min
Nullable
Not In
Numeric
Present
Regular Expression
Required
Required If
Required Unless
Required With
Required With All
Required Without
Required Without All
Same
Size
String
Timezone
Unique (Database)
URL

Tuy nhiên, trong số này chúng ta chỉ sử dụng một số validate rule cơ bản. Laravel thường xuyên kiểm tra xem có lỗi xảy ra không và tự động hiển thị nó trong view nếu nó xảy ra. Biến $errors được định nghĩa cho mọi view và mọi request, nó là một instance của Illuminate\Support\MessageBag. Các thông báo lỗi có thể được đưa lên màn hình bằng cách chèn thêm đoạn code này vào bất kỳ đâu bạn muốn hiển thị thông báo.

@if (count($errors) > 0)
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

Ví dụ sử dụng Form Validate kiểm tra thông tin nhập liệu

Ok, vẫn như thường lệ, chúng ta vào các ví dụ thực tế để tiếp cận kiến thức nhanh hơn. Chúng ta sẽ tạo ra một form đăng ký thành viên, form này nhập các thông tin như Họ và tên, địa chỉ email, password và nhập lại password, ngày sinh, trang web nếu có. Chúng ta sẽ thực hiện kiểm tra các thông tin nhập liệu như sau:

  • Họ và tên: bắt buộc, tối đa 255 ký tự.
  • Địa chỉ email: bắt buộc và phải có định dạng của email, ví dụ youremail@domain.com.
  • Mật khẩu: bắt buộc và phải có từ 6 ký tự trở lên chỉ bao gồm số và chữ.
  • Nhập lại mật khẩu: bắt buộc và phải trùng với mật khẩu.
  • Trang web: không bắt buộc nhưng nếu nhập phải là định dạng đường dẫn web, ví dụ http://yourdomain.com

 

Tạo UserController

c:\xampp\htdocs\laravel-test>php artisan make:controller UserController
Controller created successfully.

Thêm code vào UserController (app\Http\Controllers\UserController.php)

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Validator;
use DB;

class UserController extends Controller
{
    //
    public function showRegisterForm(){
    	return view('fontend.register');
    }

    public function storeUser(Request $request){
    	//dd($request->all());

    	$messages = [
		    'required' => 'Trường :attribute bắt buộc nhập.',
		    'email'    => 'Trường :attribute phải có định dạng email'
		];
		$validator = Validator::make($request->all(), [
            'name'     => 'required|max:255',
            'email'    => 'required|email',
            'password' => 'required|numeric|min:6|confirmed',
            'website'  => 'sometimes|required|url'

        ], $messages);

        if ($validator->fails()) {
            return redirect('register')
                    ->withErrors($validator)
                    ->withInput();
        } else {
        	// Lưu thông tin vào database, phần này sẽ giới thiệu ở bài về database

        	return redirect('register')
        			->with('message', 'Đăng ký thành công.');
        }
    }

}

tạo view chứa form đăng ký tên register (resources/views/fontend/register.blade.php)

@extends('layouts.default')

@section('title', 'Đăng ký')

@section('content')
    @if (count($errors) > 0)
      <div class="alert alert-danger">
          Thông tin đăng ký không đầy đủ, bạn cần chỉnh sửa như sau:
          <ul>
              @foreach ($errors->all() as $error)
                  <li>{{ $error }}</li>
              @endforeach
          </ul>
      </div>
    @endif
    @if (isset($message))
      <div class="alert alert-success">
      {{ $message }}
      </div>
    @endif

    {!! Form::open(array('url' => '/register', 'class' => 'form-horizontal')) !!}
      <div class="form-group">
         {!! Form::label('name', 'Họ và tên *', array('class' => 'col-sm-3 control-label')) !!}
         <div class="col-sm-9">
            {!! Form::text('name', '', array('class' => 'form-control')) !!}
         </div>
      </div>

      <div class="form-group">
         {!! Form::label('email', 'Địa chỉ email *', array('class' => 'col-sm-3 control-label')) !!}
         <div class="col-sm-9">
            {!! Form::email('email', '', array('class' => 'form-control')) !!}
         </div>
      </div>

      <div class="form-group">
         {!! Form::label('password', 'Mật khẩu *', array('class' => 'col-sm-3 control-label')) !!}
         <div class="col-sm-9">
            {!! Form::password('password', array('class' => 'form-control')) !!}
         </div>
      </div>

      <div class="form-group">
         {!! Form::label('password_comfirmation', 'Nhập lại mật khẩu *', array('class' => 'col-sm-3 control-label')) !!}
         <div class="col-sm-9">
            {!! Form::password('password_comfirmation', array('class' => 'form-control')) !!}
         </div>
      </div>

      <div class="form-group">
         {!! Form::label('website', 'Website', array('class' => 'col-sm-3 control-label')) !!}
         <div class="col-sm-9">
            {!! Form::text('website', '', array('class' => 'form-control')) !!}
         </div>
      </div>


      <div class="form-group">
         <div class="col-sm-offset-3 col-sm-9">
            {!! Form::submit('Đăng ký', array('class' => 'btn btn-success')) !!}
         </div>
      </div>
   {!! Form::close() !!}
@endsection

Thêm route vào routes/web.php

Route::get('register', 'UserController@showRegisterForm');
Route::post('register', 'UserController@storeUser');

Ok, vào đường dẫn http://laravel.dev/register

Nhập thông tin đăng ký trong ví dụ làm việc với database trong laravel

Nhập các thông tin và click vào đăng ký, nếu dữ liệu nhập vào không đúng quy định nó sẽ hiển thị thông báo lỗi nhập liệu

Hiển thị thông báo lỗi nhập liệu trong ví dụ validate form trong Laravel

Ok, bạn thấy đấy, việc sử dụng Validate Form trong Laravel thật đơn giản. Trước đây khi làm một website bằng PHP riêng phần validate dữ liệu thôi cũng tốn không ít giấy mực.

Hiển thị thông báo riêng khi Validate dữ liệu

Các thông báo lỗi khi validate dữ liệu trong Laravel là tiếng Anh và nội dung cố định, tuy nhiên Laravel cho phép bạn cá nhân hóa các thông báo này.

       $messages = [
		    'required' => 'Trường :attribute bắt buộc nhập.',
		    'email'    => 'Trường :attribute phải có định dạng email'
		];
		$validator = Validator::make($request->all(), [
            'name'     => 'required|max:255',
            'email'    => 'required|email',
            'password' => 'required|numeric|min:6|confirmed',
            'website'  => 'sometimes|required|url'

        ], $messages);

Kết quả như sau

Cá nhân hóa thông báo lỗi khi validate form trong Laravel

Lời kết

Kiểm tra dữ liệu người dùng nhập vào là khâu bắt buộc để đảm bảo dữ liệu “sạch” và theo đúng mong muốn thông tin cần thu thập. Validate Form trong Laravel rất đơn giản nhưng có khả năng kết hợp ra các cách thức kiếm tra rất phức tạp và khắt khe. Bài viết tạm dừng ở đây và hẹn gặp lại các bạn trong các bài viết tới liên quan đến Laravel.

15 thoughts on “Laravel Form validation – kiểm soát thông tin nhập liệu

  1. Chào ad và mọi người, tôi có một form đổi mật khẩu cần nhập mật khẩu cũ, có cách nào để validate mật khẩu cũ không, nếu khớp thì mới tiếp tục validate phần mật khẩu mới và nhập lại mật khẩu mới.

    1. Bạn cần tạo một phương thức validate riêng, ví dụ trường mật khẩu cũ là old_password, mật khẩu mới là password và xác nhận mật khẩu mới là password_comfirmation bạn có thể sử dụng mảng sau để validate:
      $rule = array(
      ‘old_password’ => ‘required|old_password:’ . Auth::user()->password,
      ‘password’ => ‘required|confirmed|min:6’,
      );
      Sau đó để tạo được phương thức validate riêng bạn cần thêm validate old_password vào file app\Providers\AppServiceProvider.php trong phương thức boot() như sau:
      public function boot()
      {
      Validator::extend(‘old_password’, function ($attribute, $value, $parameters, $validator) {
      return Hash::check($value, current($parameters));
      });
      }

      1. Cám ơn An Trần, đoạn code trên hoạt động rất tốt, tuy nhiên còn một vấn đề nữa là khi validate nó chỉ thông báo lỗi là validate.old_password khi tôi trả về lỗi trong phương thức withErrors() của form, có cách nào để hiển thị một thông báo lỗi rõ ràng hơn như “Mật khẩu cũ không đúng, bạn không thể thay đổi mật khẩu mới.” không?

        1. Chào bạn, trong bài viết mình có phần Hiển thị thông báo riêng khi Validate dữ liệu bạn có thể tham khảo nhé.

        2. $messages = [
          ‘old_password’ = ‘Mật khẩu cũ không đúng, bạn không thể thay đổi mật khẩu mới.’,
          ];
          $validator = Validator::make(Input::all(), $rule, $messages);
          Khi validate nếu mật khẩu cũ không đúng nó sẽ thông báo ‘Mật khẩu cũ không đúng, bạn không thể thay đổi mật khẩu mới.’

  2. Mình đang làm project Laravel mà bị lỗi này không biết admin có giúp được không .
    Mình muốn đặt lại tên lại trường Attributes trong FormRequest từ file Formrequest được tạo .ví dụ như trường Attribute là ‘username’ sẽ đổi thành ‘Tài khoản người dùng’.
    Mình dùng public function attributes(){ return [ ‘username’ => ‘Tài khoản người dùng’]} trong file Formrequest .Mình dùng ở laravel 5.3 thì được nhưng đổi sang 5.4 thì Attribute username vẫn còn nguyên không đổi được.
    Ở đây mình muốn cấu hình Attribute trong file Formrequest luôn chứ không muốn cấu hình trong Lang/Validation.php hay file Controller .Admin xem cho xin ý kiến .

    1. Ý bạn là muốn alias một thuộc tính đúng không? Bạn có thể sử dụng những cách sau:
      1. Alias ở câu truy vấn trên database, ví dụ SELECT `username` as ‘Tài khoản người dùng’ …
      2. Dùng Accessor
      public function getTaiKhoanNguoiDungAttribute() {
      return $this->username;
      }
      Khi đó bạn thêm một thuộc tính vào Model thông qua thuộc tính protected $appends = [‘tai_khoan_nguoi_dung’];
      3. Map tên cột thông qua thuộc tính protected $maps của Model
      $maps = [‘username’ => ‘Tài khoản người dùng’];
      Mỗi cách đều có những ưu nhược điểm khác nhau và dùng trong các hoàn cảnh khác nhau.
      Nếu không đúng bạn phản hồi lại cùng trao đổi nhé!

      1. Thanks Admin đã phản hồi .
        Ở đây chắc Admin đã hiểu nhầm ý mình .Ở đây mình muốn kiểm tra dữ liệu nhập vào trên một Form thay vì sử dụng phương thức Validator::make() ở file Controller thì mình dùng Formrequest ( php artisan make:request ) trong thư mục app/http/request .Formrequest này có cái ưu điểm rút gọn code trong Controller hơn sử dụng Validatior. Trong Formrequest thì chứa 3 phương thức chính rules ,messages và và attributes và đều trả về các mảng tương đương với $rule,$message,$attribules trong Validator:make($data,$rule,$message,$attribule) .
        Trường hợp mình bị lỗi ở trên là gặp lỗi ở phương thức attributes không thể đặt lại tên thuộc tính được .
        Ví dụ có tag sau khi submit form với điều kiện ràng buộc cate.required thì nó chuyển thông báo lỗi về.Ở đây minh muốn thay thông báo lỗi này “cate is the required” thành “thể loại is the required”.
        Nên mình dùng public function attributes(){ return [‘cate’ => ‘Thể loại’ ] } nhưng nó không được .Lỗi này mình cũng đã khắc phục được rồi .Không phải bị lỗi code mà do máy mình bị treo hay gi không biết hì hục nữa ngày không có kết quả reset máy,xóa lịch sử trình duyệt lại được .

    1. Thông thường nhập liệu trong form khi bị lỗi chúng ta muốn quay lại form nhập liệu mà không phải nhập lại gì khác nữa, Redirect::to() với phương thức withInput() sẽ truyền các giá trị bạn đã nhập trở lại form để bạn không phải nhập lại.

  3. Mình có một form nhập thông tin người dùng, trường email là một textbox có thể tạo ra thêm thông qua button “Thêm email” thực hiện bằng jquery, như vậy input email là một mảng thì phải validate như thế nào? Anh em nào biết chỉ giúp mình với.

    1. Laravel cho phép kiểm tra cả dữ liệu được nhập vào dạng mảng. Ví dụ:
      View:
      <input type=”text” name=”email[]” id=”email_1″>
      <input type=”text” name=”email[]” id=”email_2″>
      <input type=”text” name=”email[]” id=”email_3″>
      Khi đó bạn validate bằng rule như sau:
      $rule = array(
      ’email.*’ =>’required|email’
      );
      Bạn thử nhé.

Add Comment