Laravel 5x 自定義數(shù)據(jù)驗(yàn)證

Laravel本身內(nèi)置了許多好用的數(shù)據(jù)校驗(yàn)規(guī)則,拿來即用,但這遠(yuǎn)遠(yuǎn)不夠,我們需要自定義自己的驗(yàn)證規(guī)則是必要的,先看一個(gè)簡單的示例:

簡單驗(yàn)證

直接在 app\Providers\AppServiceProvider.php 里擴(kuò)展 Validator

打開 app\Providers\AppServiceProvider.php ,在 boot()方法里添加我們自己的驗(yàn)證規(guī)則,比方說我們需要一個(gè)驗(yàn)證是祖國的手機(jī)號碼(+86):

namespace App\Providers;
 
use Illuminate\Support\ServiceProvider;
use Validator;
 
class AppServiceProvider extends ServiceProvider
{
 
    public function boot()
    {
        Validator::extend('cn_phone', function($attribute, $value, $parameters) {
            return substr($value, 0, 3) == '+86';
        });
    }
 
}

參考文檔我們發(fā)現(xiàn),自定義驗(yàn)證器閉包接收四個(gè)參數(shù),分別是要驗(yàn)證的屬性名稱、屬性值、傳遞給規(guī)則的參數(shù)數(shù)組以及 Validator 實(shí)例。

這里:cn_phone 是我們將在驗(yàn)證請求類中使用的規(guī)則名稱,驗(yàn)證通過返回 TRUE , 失敗返回 FALSE,參數(shù) $attribute 是要驗(yàn)證的字段的名稱,參數(shù) $parameters 用于更復(fù)雜的驗(yàn)證規(guī)則,像 Laravel 中默認(rèn)存在的 min:xsame:field 這種。

下面演示:
定義一個(gè) /form_store 路由指向 FormControllerpostForm 方法,再定義個(gè)請求類 CreateUserRequest 依賴注入。

public function postForm(CreateUserRequest $request)
{
    return "Success!";
}

app\Http\Requests\CreateUserRequest.php

<?php 
namespace App\Http\Requests;
 
class CreateUserRequest extends Request {
 
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }
 
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'phone' => 'required|cn_phone',
        ];
    }
}

我就用自帶的 welcome.blade.php 模板頁面給大家演示一下:

<div class="content">
    <div class=title m-b-md>
        @if(count($errors) > 0)
            @foreach($errors->all() as $error)
                <li>{{ $error }}</li>  
            @endforeach
        @endif
        <form action="{{ url('form_store') }}" method="post">
            {{ csrf_field() }}
            <input type="text" name="phone">
            <input type="submit" value="確認(rèn)">
        </form>
    </div>
</div>

preview:

image

好像出錯(cuò)提示出來了,有木有,但是這不是我們想要的,我們要自定義一個(gè)錯(cuò)誤消息。打開 resources/lang/en/validation.php 找到

'custom' => [
        'attribute-name' => [
            'rule-name' => 'custom-message',
        ],
    ],

按照此格式要求,改寫成我們定義的驗(yàn)證字段和對應(yīng)的返回錯(cuò)誤消息提示:

'custom' => [
        'phone' => [
            'zn_phone' => '請加手機(jī)號的國際區(qū)號+86',
        ],
    ],

再次驗(yàn)證:


image

這還遠(yuǎn)遠(yuǎn)不夠,對于復(fù)雜的數(shù)據(jù)驗(yàn)證呢?

復(fù)雜驗(yàn)證

自定義的 Validator
假設(shè)有這么個(gè)驗(yàn)證要求,是 phoneemail 當(dāng)輸入手機(jī)號時(shí),郵箱就不能同時(shí)輸入(什么奇葩需求),來看如何定義自己的驗(yàn)證類:

首先我們想到的是這個(gè)自定義驗(yàn)證類放哪里好呢?這里我個(gè)人建議在 app 下新建一個(gè)目錄,我取名為 Librarys ,這里放一些公共函數(shù)庫,第三方支付模塊以及我們的自定義驗(yàn)證類等等。上代碼:

app\Providers\MyValidator.php

<?php 
namespace App\Librarys;
 
use Illuminate\Validation\Validator;
 
class MyValidator extends Validator {
 
    public function validateEmptyWith($attribute, $value, $parameters)
    {
        return ($value != '' && $this->getValue($parameters[0]) != '') ? false : true;
    }
}

App\Providers\AppServiceProvider

<?php

namespace App\Providers;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;
use App\Librarys;
class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {

        Validator::resolver(function($translator, $data, $rules, $messages)
        {
            return new MyValidator($translator, $data, $rules, $messages);
        });
    }

resources\lang\en\validation.php

'custom' => [
    'phone' => [
        'empty_with' => '只能填一個(gè)字段,不能同時(shí)',
    ],
],

定義好驗(yàn)證類,這個(gè)類只是擴(kuò)展了 Laravel的內(nèi)置驗(yàn)證基類,想讓我們的驗(yàn)證規(guī)則被 Laravel “承認(rèn)”,必須進(jìn)入 AppServiceProviderboot 方法啟動載入。

分析返回條件,想一想如果達(dá)不到上面的“需求”,那意味著:

  • 不輸入手機(jī)號,輸入郵箱
  • 不輸入手機(jī)號,不輸入郵箱
  • 兩者都不輸入

滿足這三個(gè)條件即為驗(yàn)證通過,那么取反后判斷條件如上,大家不用糾結(jié)這個(gè)判斷,著重看 $this->getValue($parameters[0]) 這個(gè)方法,參數(shù)數(shù)組 $parameters[0] 為對應(yīng)第一個(gè)驗(yàn)證規(guī)則,類似 min:xxx, 這里是 empty_with:email,通過該參數(shù)獲取 email 對應(yīng)的值傳入 getValue() 中再返回 bool 值。問題來了,為什么是 empty_with:email 不是 emptyWith:email 或其他的呢,其實(shí)框架內(nèi)部已經(jīng)為我們處理好了名稱的對應(yīng)的格式,我們自定義的驗(yàn)證類里的驗(yàn)證方法必須以 validate 開頭然后接小駝峰命名,對應(yīng)驗(yàn)證規(guī)則的名稱就是下劃線的方式。這點(diǎn)要牢記

效果圖就不放了,大家可以嘗試下,這樣,基本上我們單獨(dú)自定義的驗(yàn)證類結(jié)構(gòu)就比較清晰了,利用面向?qū)ο蟮姆绞匠殡x出獨(dú)立的驗(yàn)證類,更符合單一職責(zé)原則,這里其實(shí)還可以優(yōu)化,比如獨(dú)立出一個(gè) ValidationExtensionServiceProvider extends ServiceProvider:

class ValidationExtensionServiceProvider extends ServiceProvider
{

    public function register() {}

    public function boot()
    {
        $this->app->validator->resolver( function( $translator, $data, $rules, $messages = array(), $customAttributes = array() ) {
            return new ValidatorExtended( $translator, $data, $rules, $messages, $customAttributes );
        } );
    }
}   

然后告訴 laravel 載入該服務(wù),app/config/app.php 里添加進(jìn)去。這樣就更符合 Laravel Way 了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、簡介 Laravel 提供了多種方法來驗(yàn)證應(yīng)用輸入數(shù)據(jù)。默認(rèn)情況下,Laravel 的控制器基類使用Valid...
    伊Summer閱讀 1,615評論 0 3
  • 原文鏈接 必備品 文檔:Documentation API:API Reference 視頻:Laracasts ...
    layjoy閱讀 8,702評論 0 121
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,540評論 19 139
  • 驗(yàn)證 簡介 Laravel 對驗(yàn)證應(yīng)用的輸入數(shù)據(jù)提供了多中途徑的實(shí)現(xiàn)。默認(rèn)的,Laravel 的基礎(chǔ)控制器類使用了...
    Dearmadman閱讀 10,372評論 5 8
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,940評論 25 709

友情鏈接更多精彩內(nèi)容