国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

表單驗(yàn)證

表單驗(yàn)證


表單驗(yàn)證

簡(jiǎn)介

Laravel 提供了幾種不同的方法來(lái)驗(yàn)證傳入應(yīng)用程序的數(shù)據(jù)。默認(rèn)情況下,Laravel 的控制器基類使用 ValidatesRequests Trait,它提供了一種方便的方法去使用各種強(qiáng)大的驗(yàn)證規(guī)則來(lái)驗(yàn)證傳入的 HTTP 請(qǐng)求。

快速驗(yàn)證

要了解 Laravel 強(qiáng)大的驗(yàn)證功能,讓我們看一個(gè)驗(yàn)證表單并將錯(cuò)誤消息顯示回給用戶的完整示例。

定義路由

首先,讓我們假設(shè)在 routes/web.php 文件中定義了下面這些路由:

Route::get('post/create', 'PostController@create');
Route::post('post', 'PostController@store');

顯然,GET 路由會(huì)顯示一個(gè)供用戶創(chuàng)建一個(gè)新的博客帖子的表單,而 POST 路由會(huì)將新的博客文章存儲(chǔ)在數(shù)據(jù)庫(kù)中。

創(chuàng)建路由器

下面讓我們一起來(lái)看看處理這些路由的控制器, store 方法暫時(shí)留空。

<?php
  namespace App\Http\Controllers;
  use Illuminate\Http\Request;
  use App\Http\Controllers\Controller;
  class PostController extends Controller{    
      /**
     * 顯示創(chuàng)建博客文章的表單。
     *
     * @return Response
     */   
  public function create()   
   {       
    return view('post.create');    
    }   
     /**
     * 保存一篇新的博客文章。
     *
     * @param  Request  $request
     * @return Response
     */   
    public function store(Request $request)   
     {      
       // 驗(yàn)證并存儲(chǔ)博客文章...   
      }
   }

編寫驗(yàn)證器邏輯

現(xiàn)在我們開始在 store 方法中編寫邏輯來(lái)驗(yàn)證新的博客文章。為此,我們將使用 Illuminate\Http\Request 對(duì)象提供的 validate 方法 。如果驗(yàn)證通過,代碼就可以正常的運(yùn)行。如果驗(yàn)證失敗,則會(huì)拋出異常,并自動(dòng)將對(duì)應(yīng)的錯(cuò)誤響應(yīng)返回給用戶。在典型的 HTTP 請(qǐng)求的情況下,會(huì)生成一個(gè)重定向響應(yīng),而對(duì)于 AJAX 請(qǐng)求則會(huì)發(fā)送 JSON 響應(yīng)。

讓我們接著回到 store 方法來(lái)深入理解 validate 方法:

/**
 * 保存一篇新的博客文章。
 *
 * @param  Request  $request
 * @return Response
 */
 public function store(Request $request){ 
    $validatedData = $request->validate([      
      'title' => 'required|unique:posts|max:255',        
      'body' => 'required',    
    ]);    
    // 博客文章驗(yàn)證通過
  }

如你所見,我們將所需的驗(yàn)證規(guī)則傳遞至 validate 方法中。另外再提醒一次,如果驗(yàn)證失敗,會(huì)自動(dòng)生成一個(gè)對(duì)應(yīng)的響應(yīng)。如果驗(yàn)證通過,那我們的控制器將會(huì)繼續(xù)正常運(yùn)行。

首次驗(yàn)證失敗后停止運(yùn)行

如果你希望在某個(gè)屬性第一次驗(yàn)證失敗后停止運(yùn)行驗(yàn)證規(guī)則,你需要附加 bail 規(guī)則到該屬性:

$request->validate([   
 'title' => 'bail|required|unique:posts|max:255',    
 'body' => 'required',
]);

在這個(gè)例子中,如果 title 字段沒有通過 unique 規(guī)則,那么程序就不會(huì)繼續(xù)檢查 max 規(guī)則。規(guī)則會(huì)按照分配的順序來(lái)驗(yàn)證。

關(guān)于數(shù)組數(shù)據(jù)的注意實(shí)現(xiàn)

如果你的 HTTP 請(qǐng)求包含一個(gè) 「嵌套」 參數(shù)(即數(shù)組),那你可以在驗(yàn)證規(guī)則中通過 「點(diǎn)」 語(yǔ)法來(lái)指定這些參數(shù)。

$request->validate([   
 'title' => 'required|unique:posts|max:255',    
 'author.name' => 'required',    
 'author.description' => 'required',
]);

顯示驗(yàn)證錯(cuò)誤信息

如果傳入的請(qǐng)求參數(shù)未通過給定的驗(yàn)證規(guī)則呢?正如前面所提到的,Laravel 會(huì)自動(dòng)把用戶重定向到之前的位置。另外,所有的驗(yàn)證錯(cuò)誤信息會(huì)被自動(dòng) 存儲(chǔ)到 session 中。

重申一次,我們不必在 GET 路由中將錯(cuò)誤消息顯式綁定到視圖。因?yàn)?Lavarel 會(huì)檢查在 Session 數(shù)據(jù)中的錯(cuò)誤信息,并自動(dòng)將其綁定到視圖(如果這個(gè)視圖文件存在)。而其中的變量 $errorsIlluminate\Support\MessageBag 的一個(gè)實(shí)例。要獲取關(guān)于這個(gè)對(duì)象的更多信息,請(qǐng)  查閱這個(gè)文檔 。

{tip} $errors 變量被 Web 中間件組提供的 Illuminate\View\Middleware\ShareErrorsFromSession 中間件綁定到視圖中。 當(dāng)這個(gè)中間件被應(yīng)用后,在你的視圖中就可以獲取到 $error 變量 , 可以使一直假定 $errors 變量存在并且可以安全地使用。

在上面的例子中,當(dāng)驗(yàn)證失敗的時(shí)候,用戶將會(huì)被重定向到控制器的 create 方法,使我們能在視圖中顯示錯(cuò)誤信息:

<!-- /resources/views/post/create.blade.php -->
<h1>創(chuàng)建文章</h1>
@if ($errors->any())  
  <div class="alert alert-danger">     
     <ul>
       @foreach ($errors->all() as $error)                
       <li>{{ $error }}</li>
            @endforeach
      </ul>    
   </div>
 @endif
 <!-- 創(chuàng)建文章表單 -->

關(guān)于可選字段的注意事項(xiàng)

默認(rèn)情況下,在 Laravel 應(yīng)用的全局中間件堆棧 App\Http\Kernel 類中包含了 TrimStringsConvertEmptyStringsToNull 中間件。因此,如果你不希望驗(yàn)證程序?qū)?null 值視為無(wú)效的話,那就需要將「可選」的請(qǐng)求字段標(biāo)記為 nullable,舉個(gè)例子:

$request->validate([  
  'title' => 'required|unique:posts|max:255',    
  'body' => 'required',    
  'publish_at' => 'nullable|date',
]);

在這個(gè)例子里,我們指定 publish_at 字段可以為 null 或者一個(gè)有效的日期格式。如果 nullable 的修飾詞沒有被添加到規(guī)則定義中,驗(yàn)證器會(huì)認(rèn)為 null 是一個(gè)無(wú)效的日期格式。

AJAX 請(qǐng)求 & 驗(yàn)證

在這個(gè)例子中,我們使用傳統(tǒng)的表單將數(shù)據(jù)發(fā)送到應(yīng)用程序。但實(shí)際情況中,很多程序都會(huì)使用 AJAX 來(lái)發(fā)送請(qǐng)求。當(dāng)我們對(duì) AJAX 的請(qǐng)求中使用 validate 方法時(shí),Laravel 并不會(huì)生成一個(gè)重定向響應(yīng),而是會(huì)生成一個(gè)包含所有驗(yàn)證錯(cuò)誤信息的 JSON 響應(yīng)。這個(gè) JSON 響應(yīng)會(huì)包含一個(gè) HTTP 狀態(tài)碼 422 被發(fā)送出去。

驗(yàn)證表單請(qǐng)求

創(chuàng)建表單請(qǐng)求驗(yàn)證

面對(duì)更復(fù)雜的驗(yàn)證情境中,你可以創(chuàng)建一個(gè)「表單請(qǐng)求」來(lái)處理更為復(fù)雜的邏輯。表單請(qǐng)求是包含驗(yàn)證邏輯的自定義請(qǐng)求類??墒褂?Artisan 命令 make:request 來(lái)創(chuàng)建表單請(qǐng)求類:

php artisan make:request StoreBlogPost

新生成的類保存在 app/Http/Requests 目錄下。如果這個(gè)目錄不存在,運(yùn)行 make:request 命令時(shí)它會(huì)被創(chuàng)建出來(lái)。讓我們添加一些驗(yàn)證規(guī)則到 rules 方法中:

/**
 * 獲取適用于請(qǐng)求的驗(yàn)證規(guī)則。
 *
 * @return array
 */
 public function rules(){   
  return [       
    'title' => 'required|unique:posts|max:255',        
    'body' => 'required',    
    ];
  }

{tip} 你可以向 rules 方法傳入所需的任何依賴項(xiàng)。他們會(huì)自動(dòng)被 Laravel 提供的 服務(wù)容器 自動(dòng)解析。

驗(yàn)證規(guī)則是如何運(yùn)行的呢?你所需要做的就是在控制器方法中類型提示傳入的請(qǐng)求。在調(diào)用控制器方法之前驗(yàn)證傳入的表單請(qǐng)求,這意味著你不需要在控制器中寫任何驗(yàn)證邏輯:

/**
 * 存儲(chǔ)傳入的博客文章。
 *
 * @param  StoreBlogPost  $request
 * @return Response
 */
 public function store(StoreBlogPost $request){   
  // 傳入的請(qǐng)求通過驗(yàn)證...    
  // 獲取通過驗(yàn)證的數(shù)據(jù)...    
  $validated = $request->validated();
 }

如果驗(yàn)證失敗,就會(huì)生成一個(gè)讓用戶返回到先前的位置的重定向響應(yīng)。這些錯(cuò)誤也會(huì)被閃存到 session 中,以便這些錯(cuò)誤都可以在頁(yè)面中顯示出來(lái)。如果傳入的請(qǐng)求是 AJAX,會(huì)向用戶返回具有 422 狀態(tài)代碼和驗(yàn)證錯(cuò)誤信息的 JSON 數(shù)據(jù)的 HTTP 響應(yīng)。

添加表單請(qǐng)求后鉤子

如果你想在表單請(qǐng)求「之后」添加鉤子,可以使用 withValidator 方法。這個(gè)方法接收一個(gè)完整的驗(yàn)證構(gòu)造器,允許你在驗(yàn)證結(jié)果返回之前調(diào)用任何方法:

/**
 *  配置驗(yàn)證器實(shí)例。
 *
 * @param  \Illuminate\Validation\Validator  $validator
 * @return void
 */
 public function withValidator($validator){ 
    $validator->after(function ($validator) {        
         if ($this->somethingElseIsInvalid()) {           
              $validator->errors()->add('field', 'Something is wrong with this field!');        
             }   
         });
   }

表單請(qǐng)求授權(quán)驗(yàn)證

表單請(qǐng)求類內(nèi)也包含了 authorize 方法。在這個(gè)方法中,你可以檢查經(jīng)過身份驗(yàn)證的用戶確定其是否具有更新給定資源的權(quán)限。比方說(shuō),你可以判斷用戶是否擁有更新文章評(píng)論的權(quán)限:

/**
 * 判斷用戶是否有權(quán)限做出此請(qǐng)求。
 *
 * @return bool
 */
 public function authorize(){  
   $comment = Comment::find($this->route('comment'));    
   return $comment && $this->user()->can('update', $comment);
 }

由于所有的表單請(qǐng)求都是繼承了 Laravel 中的請(qǐng)求基類,所以我們可以使用 user 方法去獲取當(dāng)前認(rèn)證登錄的用戶。同時(shí)請(qǐng)注意上述例子中對(duì) route 方法的調(diào)用。這個(gè)方法允許你在被調(diào)用的路由上獲取其定義的 URI 參數(shù),譬如下面例子中的 {comment} 參數(shù):

Route::post('comment/{comment}');

如果 authorize 方法返回 false,則會(huì)自動(dòng)返回一個(gè)包含 403 狀態(tài)碼的 HTTP 響應(yīng),也不會(huì)運(yùn)行控制器的方法。

如果你打算在應(yīng)用程序的其它部分處理授權(quán)邏輯,只需從 authorize 方法返回 true

/**
 * 判斷用戶是否有權(quán)限進(jìn)行此請(qǐng)求。
 *
 * @return bool
 */
 public function authorize(){  
   return true;
  }

{tip} 你可以向 authorize 方法傳入所需的任何依賴項(xiàng)。他們會(huì)自動(dòng)被 Laravel 提供的 服務(wù)容器 自動(dòng)解析。

自定義錯(cuò)誤消息

你可以通過重寫表單請(qǐng)求的 messages 方法來(lái)自定義錯(cuò)誤消息。此方法應(yīng)返回屬性 / 規(guī)則對(duì)數(shù)組及其對(duì)應(yīng)錯(cuò)誤消息:

/**
 * 獲取已定義驗(yàn)證規(guī)則的錯(cuò)誤消息。
 *
 * @return array
 */
 public function messages(){  
   return [       
    'title.required' => 'A title is required',        
    'body.required'  => 'A message is required',    
    ];
  }

自定義驗(yàn)證屬性

如果你希望將驗(yàn)證消息的 :attribute 部分替換為自定義屬性名稱,則可以重寫 attributes 方法來(lái)指定自定義名稱。此方法應(yīng)返回屬性 / 名稱對(duì)的數(shù)組:

/**
 * 獲取驗(yàn)證錯(cuò)誤的自定義屬性。
 *
 * @return array
 */
 public function attributes(){  
   return [      
     'email' => 'email address',    
     ];
   }

手動(dòng)創(chuàng)建驗(yàn)證器

如果你不想在請(qǐng)求上使用 validate 方法,你可以通過 Validator facade 手動(dòng)創(chuàng)建一個(gè)驗(yàn)證器示例。
Validator facade 上的 make 方法創(chuàng)建一個(gè)驗(yàn)證器示例:

<?php
   namespace App\Http\Controllers;use Validator;
   use Illuminate\Http\Request;
   use App\Http\Controllers\Controller;
   class PostController extends Controller{    
      /**
     * 保存一篇新的博客文章。
     *
     * @param  Request  $request
     * @return Response
     */   
    public function store(Request $request)   
     {       
      $validator = Validator::make($request->all(), [      
            'title' => 'required|unique:posts|max:255',            
            'body' => 'required',        
          ]);       
        if ($validator->fails()) {          
          return redirect('post/create')                       
           ->withErrors($validator)                        
           ->withInput();       
           }       
       // Store the blog post...  
        }
      }

傳給 make 方法的第一個(gè)參數(shù)是需要驗(yàn)證的數(shù)據(jù)。第二個(gè)參數(shù)則是該數(shù)據(jù)的驗(yàn)證規(guī)則。

如果驗(yàn)證失敗,則可以使用 withErrors 方法把錯(cuò)誤消息閃存到 Session 。使用這個(gè)方法進(jìn)行重定向后, $errors 變量會(huì)自動(dòng)和視圖共享,你可以把這些消息顯示給用戶。 withErrors 方法接收驗(yàn)證器、MessageBag 或 PHP Array 。

自動(dòng)重定向

如果你想手動(dòng)創(chuàng)建驗(yàn)證器實(shí)例,又想使用 validates 方法提供的自動(dòng)重定向,那么你可以在現(xiàn)有的驗(yàn)證器示例上調(diào)用 validate 方法。如果驗(yàn)證失敗,用戶將會(huì)自動(dòng)重定向。在 AJAX 請(qǐng)求中,則會(huì)返回 JSON 格式的響應(yīng)。

Validator::make($request->all(), [   
 'title' => 'required|unique:posts|max:255',    
 'body' => 'required',
])->validate();

命名錯(cuò)誤包

如果你一個(gè)頁(yè)面中有多個(gè)表單,你可以通過命名錯(cuò)誤包來(lái)檢索特定表單的錯(cuò)誤消息。只需給 withErrors 方法傳遞一個(gè)名字作為第二個(gè)參數(shù)

return redirect('register')          
  ->withErrors($validator, 'login');

然后你就可以從 $errors 變量中獲取指定表單的錯(cuò)誤消息:

{{ $errors->login->first('email') }}

驗(yàn)證后鉤子

驗(yàn)證器還允許你添加在驗(yàn)證成功之后允許的回調(diào)函數(shù),以便你進(jìn)行下一步的驗(yàn)證,甚至在消息集合中添加更多的錯(cuò)誤消息。使用它只需在驗(yàn)證實(shí)例上使用 after 方法:

$validator = Validator::make(...);$validator->after(function ($validator) {   
 if ($this->somethingElseIsInvalid()) {     
    $validator->errors()->add('field', 'Something is wrong with this field!');   
     }
   });
 if ($validator->fails()) {  
   //
 }

處理錯(cuò)誤消息

Validator 實(shí)例上調(diào)用 errors 方法后,你會(huì)得到一個(gè) Illuminate\Support\MessageBag 實(shí)例,它擁有各種方便的方法處理錯(cuò)誤信息。自動(dòng)提供給所有視圖的 $ errors 變量,也是 MessageBag 類的一個(gè)實(shí)例。

查看特定字段的第一個(gè)錯(cuò)誤信息

要查看特定字段的第一個(gè)錯(cuò)誤消息,可以使用 first 方法:

$errors = $validator->errors();echo $errors->first('email');

查看特定字段的所有錯(cuò)誤消息

如果你需要獲取指定字段的所有錯(cuò)誤消息的數(shù)組,則可以使用 get 方法:

foreach ($errors->get('email') as $message) {  
  //
}

如果要驗(yàn)證表單的數(shù)組字段,你可以使用 * 來(lái)獲取每個(gè)數(shù)組元素的所有錯(cuò)誤消息:

foreach ($errors->get('attachments.*') as $message) { 
   //
}

查看所有字段的所有錯(cuò)誤消息

如果你想要得到所有字段的所有錯(cuò)誤消息,可以使用 all 方法:

foreach ($errors->all() as $message) { 
   //
}

判斷特定字段是否含有錯(cuò)誤消息

has 方法可以被用來(lái)判斷給定的字段是否存在錯(cuò)誤信息:

if ($errors->has('email')) { 
   //
}

自定義錯(cuò)誤消息

如果有需要的話,你也可以使用自定義錯(cuò)誤消息取代默認(rèn)值進(jìn)行驗(yàn)證。有幾種方法可以指定自定義消息。首先,你可以將自定義消息作為第三個(gè)參數(shù)傳遞給 Validator::make 方法:

$messages = [  
  'required' => 'The :attribute field is required.',
 ];
 $validator = Validator::make($input, $rules, $messages);

在這個(gè)例子中,:attribute 占位符會(huì)被驗(yàn)證字段的實(shí)際名稱取代。除此之外,你還可以在驗(yàn)證消息中使用其它占位符。例如:

$messages = [   
 'same'=> 'The :attribute and :other must match.',    
 'size'=> 'The :attribute must be exactly :size.',    
 'between' => 'The :attribute value :input is not between :min - :max.',    
 'in'=> 'The :attribute must be one of the following types: :values',
];

為給定屬性指定自定義消息

有時(shí)候你可能只想為特定的字段自定義錯(cuò)誤消息。只需在屬性名稱后使用「點(diǎn)」語(yǔ)法來(lái)指定驗(yàn)證的規(guī)則即可:

$messages = [ 
   'email.required' => 'We need to know your e-mail address!',
 ];

在語(yǔ)言文件中指定自定義消息

在大多數(shù)情況下,您可能會(huì)在語(yǔ)言文件中指定自定義消息,而不是直接將它們傳遞給 Validator。為此,需要把你的消息放置于 resources/lang/xx/validation.php 語(yǔ)言文件內(nèi)的 custom 數(shù)組中。

'custom' => [  
  'email' => [    
      'required' => 'We need to know your e-mail address!',  
      ],
    ],

在語(yǔ)言文件中指定自定義屬性

如果你希望將驗(yàn)證消息的 :attribute 占位符替換為自定義屬性名稱,你可以在 resources/lang/xx/validation.php 語(yǔ)言文件的 attributes 數(shù)組中指定自定義名稱:

'attributes' => [  
  'email' => 'email address',
 ],

在語(yǔ)言文件中指定自定義值

有時(shí)可能需要將驗(yàn)證消息的 :value 占位符替換為值的自定義文字。例如,如果 payment_type 的值為 cc,使用以下驗(yàn)證規(guī)則,該規(guī)則指定需要信用卡號(hào):

$request->validate([  
  'credit_card_number' => 'required_if:payment_type,cc'
 ]);

如果此驗(yàn)證規(guī)則失敗,則會(huì)產(chǎn)生以下錯(cuò)誤消息:

    當(dāng)payment type為cc時(shí),credit card number 不能為空。

您可以通過定義 values 數(shù)組,在 validation 語(yǔ)言文件中指定自定義值表示,而不是顯示 cc 作為支付類型值:

'values' => [ 
   'payment_type' => [    
       'cc' => '信用卡' 
        ],
    ],

現(xiàn)在,如果驗(yàn)證規(guī)則失敗,它將產(chǎn)生以下消息:

    當(dāng)payment type 為信用卡時(shí),credit card number不能為空。

可用驗(yàn)證規(guī)則

以下是所有可用驗(yàn)證規(guī)則及其功能的列表:

accepted

驗(yàn)證字段必須是 yes, on, 1,或 true。這在確認(rèn)「服務(wù)條款」是否同意時(shí)相當(dāng)有用。

active_url

根據(jù) PHP 函數(shù) dns_get_record,驗(yàn)證字段必須具有有效的 A 或 AAAA 記錄。

after:date

驗(yàn)證字段必須是給定日期之后的值。日期值將傳遞到 PHP 函數(shù) strtotime

'start_date' => 'required|date|after:tomorrow'

您可以指定另一個(gè)要與日期進(jìn)行比較的字段,而不是傳遞要由 strtotime 處理的日期字符串:

'finish_date' => 'required|date|after:start_date'

after_or_equal:date

驗(yàn)證字段必須是在給定日期之后或與此日期相同的值。更多信息,請(qǐng)參閱 after 規(guī)則。

alpha

驗(yàn)證字段必須完全由字母構(gòu)成。

alpha_dash

驗(yàn)證字段可能包含字母、數(shù)字,以及破折號(hào) (-) 和下劃線 ( _ )。

alpha_num

驗(yàn)證字段必須是完全是字母、數(shù)字。

array

驗(yàn)證的字段必須是一個(gè) PHP 數(shù)組。

bail

在第一次驗(yàn)證失敗后停止運(yùn)行驗(yàn)證規(guī)則。

before:date

驗(yàn)證字段必須是在給定日期之前。這個(gè)日期值將會(huì)被傳遞給  PHP 的  strtotime 函數(shù)來(lái)計(jì)算。

before_or_equal:date

驗(yàn)證字段必須是在給定日期之前或與之相同的日期。這個(gè)日期值將會(huì)被傳遞給  PHP 的  strtotime 函數(shù)來(lái)計(jì)算。

between:min,max

驗(yàn)證字段的大小必須在給定的  min 和  max 之間。字符串、數(shù)字、數(shù)組和文件的計(jì)算方式都使用  size 方法。

boolean

驗(yàn)證的字段必須可以轉(zhuǎn)換為 Boolean 類型。 可接受的輸入為 true, false, 1, 0, "1", 和 "0"

confirmed

驗(yàn)證字段必須具有匹配字段 foo_confirmation。例如,驗(yàn)證字段為 password ,輸入中必須存在與之匹配的 password_confirmation 字段。

date

根據(jù) PHP 函數(shù) strtotime,驗(yàn)證字段必須是有效的日期。

date_equals:date

驗(yàn)證字段必須等于給定日期。日期將傳遞到 PHP 函數(shù) strtotime。

date_format:format

驗(yàn)證字段必須匹配給定的日期格式。當(dāng)驗(yàn)證某個(gè)字段的時(shí)候,你應(yīng)該 只使用 date 或者 date_format ,而不是同時(shí)使用。

different:field

驗(yàn)證字段必須具有與 field 不同的值。

digits:value

驗(yàn)證字段必須為 numeric ,且必須具有_value_的確切長(zhǎng)度。

digits_between:min,max

驗(yàn)證的字段的長(zhǎng)度必須在給定的  min 和  max 之間。

dimensions

驗(yàn)證中的文件必須是圖片,并且符合指定的規(guī)則約束:

'avatar' => 'dimensions:min_width=100,min_height=200'

可用的約束為: min_width, max_width, min_height, max_height, width, height, ratio。

ratio 限制應(yīng)該表示為寬度除以高度。 這可以通過使用像 3/2 的表達(dá)式 或者一個(gè)浮點(diǎn)數(shù),像 1.5 來(lái)指定:

'avatar' => 'dimensions:ratio=3/2'

由于此規(guī)則需要多個(gè)參數(shù),你可以使用 Rule::dimensions 方法流暢地構(gòu)造規(guī)則:

use Illuminate\Validation\Rule;
Validator::make($data, [  
  'avatar' => [     
     'required',        
     Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),    
   ],
  ]);

distinct

當(dāng)驗(yàn)證數(shù)組時(shí),驗(yàn)證字段不得包含任何重復(fù)值。

'foo.*.id' => 'distinct'

email

驗(yàn)證字段必須為正確格式的電子郵件地址。

exists:table,column

驗(yàn)證字段必須存在于給定的數(shù)據(jù)庫(kù)表中。

Exists 規(guī)則基本用法

'state' => 'exists:states'

如果未指定 column 選項(xiàng),則將使用字段名稱。

指定自定義的表字段

'state' => 'exists:states,abbreviation'

有時(shí),你可能需要指定要用于「exists」查詢的特定數(shù)據(jù)庫(kù)連接。你可以使用「點(diǎn)」語(yǔ)法將連接名稱添加到表名稱前來(lái)完成此操作:

'email' => 'exists:connection.staff,email'

如果您想自定義驗(yàn)證規(guī)則執(zhí)行的查詢,您可以使用 Rule 類來(lái)流暢地定義規(guī)則。在下面的例子中,我們還以數(shù)組的形式指定驗(yàn)證規(guī)則,而不是使用 | 字符來(lái)分隔它們:

use Illuminate\Validation\Rule;
Validator::make($data, [  
  'email' => [      
    'required',        
    Rule::exists('staff')->where(function ($query) {  
           $query->where('account_id', 1);    
        }),
     ],
  ]);

file

驗(yàn)證的字段必須是成功上傳的文件。

filled

驗(yàn)證字段存在時(shí)不得為空。

gt:field

驗(yàn)證字段必須大于給定的 field。兩個(gè)字段必須是相同的類型。字符串、數(shù)字、數(shù)組和文件都使用 size 進(jìn)行相同的評(píng)估。

gte:field

驗(yàn)證字段必須大于或等于給定的  field。兩個(gè)字段必須是相同的類型。字符串、數(shù)字、數(shù)組和文件都使用 size 進(jìn)行相同的評(píng)估。

image

驗(yàn)證的文件必須是圖片 (jpeg, png, bmp, gif, 或 svg)

in:foo,bar,...

驗(yàn)證字段必須包含在給定的值列表中。由于此規(guī)則通常要求您 implode 數(shù)組,因此可以使用 Rule :: in 方法流暢地構(gòu)造規(guī)則:

use Illuminate\Validation\Rule;
Validator::make($data, [  
  'zones' => [      
    'required',        
    Rule::in(['first-zone', 'second-zone']),  
   ],
]);

in_array:anotherfield

驗(yàn)證的字段必須存在于另一個(gè)字段 anotherfield 的值中。

integer

驗(yàn)證的字段必須是整數(shù)。

ip

驗(yàn)證的字段必須是 IP 地址。

ipv4

驗(yàn)證的字段必須是 IPv4 地址。

ipv6

驗(yàn)證的字段必須是 IPv6 地址。

json

驗(yàn)證的字段必須是有效的 JSON 字符串。

lt:field

驗(yàn)證中的字段必須小于給定的字段。這兩個(gè)字段必須是相同的類型。字符串、數(shù)值、數(shù)組和文件大小的計(jì)算方式與 size 方法進(jìn)行評(píng)估。

lte:field

驗(yàn)證中的字段必須小于或等于給定的字段。這兩個(gè)字段必須是相同的類型。字符串、數(shù)值、數(shù)組和文件大小的計(jì)算方式與  size  方法進(jìn)行評(píng)估。

max:value

驗(yàn)證中的字段必須小于或等于 value。字符串、數(shù)字、數(shù)組或是文件大小的計(jì)算方式都用 size 方法進(jìn)行評(píng)估。

mimetypes:text/plain,...

驗(yàn)證的文件必須與給定 MIME 類型之一匹配:

'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'

要確定上傳文件的 MIME 類型,會(huì)讀取文件的內(nèi)容來(lái)判斷 MIME 類型,這可能與客戶端提供的 MIME 類型不同。

mimes:foo,bar,...

驗(yàn)證的文件必須具有與列出的其中一個(gè)擴(kuò)展名相對(duì)應(yīng)的 MIME 類型。

MIME 規(guī)則基本用法

'photo' => 'mimes:jpeg,bmp,png'

即使你可能只需要驗(yàn)證指定擴(kuò)展名,但此規(guī)則實(shí)際上會(huì)驗(yàn)證文件的 MIME 類型,其通過讀取文件的內(nèi)容以猜測(cè)它的 MIME 類型。

可以在以下鏈接中找到完整的 MIME 類型列表及其相應(yīng)的擴(kuò)展名:
https://svn.apache.org/repos/asf/httpd/htt...

min:value

驗(yàn)證中的字段必須具有最小值。字符串、數(shù)字、數(shù)組或是文件大小的計(jì)算方式都用 size 方法進(jìn)行評(píng)估。

not_in:foo,bar,...

驗(yàn)證的字段不能包含在給定的值列表中。Rule::notIn 方法可以用來(lái)構(gòu)建規(guī)則:

use Illuminate\Validation\Rule;
Validator::make($data, [  
  'toppings' => [     
     'required',        
     Rule::notIn(['sprinkles', 'cherries']), 
     ],
 ]);

not_regex:pattern

驗(yàn)證中的字段必須與給定的正則表達(dá)式不匹配。

在內(nèi)部,此規(guī)則使用 PHP preg_match 函數(shù)。輸入的值應(yīng)遵循 preg_match 函數(shù)所需的相同格式,因此也包括有效的分隔符。例如:'email' => 'not_regex:/^.+$/i'。

注意: 當(dāng)使用 regex/not_regex 模式時(shí),可能需要在數(shù)組中指定規(guī)則,而不是使用管道分隔符,尤其是在正則表達(dá)式包含管道字符的情況下。

nullable

驗(yàn)證的字段可以為 null。這在驗(yàn)證基本數(shù)據(jù)類型時(shí)特別有用,例如可以包含空值的字符串和整數(shù)。

numeric

驗(yàn)證的字段必須是數(shù)字。

present

驗(yàn)證的字段必須存在于輸入數(shù)據(jù)中,但可以為空。

regex:pattern

驗(yàn)證的字段必須與給定的正則表達(dá)式匹配。

在內(nèi)部,此規(guī)則使用 PHP preg_match 函數(shù)。輸入的值應(yīng)遵循 preg_match 函數(shù)所需的相同格式,因此也包括有效的分隔符。例如:'email' => 'regex:/^.+@.+$/i'。

注意: 當(dāng)使用 regex 規(guī)則時(shí),你必須使用數(shù)組,而不是使用 | 分隔符,特別是如果正則表達(dá)式包含 | 字符。

required

驗(yàn)證的字段必須存在于輸入數(shù)據(jù)中,而不是空。如果滿足以下條件之一,則字段被視為「空」:

  • 值為 null
  • 值為空字符串。
  • 值為空數(shù)組或空 Countable 對(duì)象。
  • 值為無(wú)路徑的上傳文件。

required_if:anotherfield,value,...

如果 anotherfield 字段等于任一 value,驗(yàn)證的字段必須出現(xiàn)且不為空 。

如果你想為 required_if 規(guī)則構(gòu)造一個(gè)更復(fù)雜的條件,你可以使用 Rule::requiredIf 方法。此方法接受布爾值或閉包。當(dāng)傳遞一個(gè)閉包時(shí),應(yīng)返回 truefalse 以確認(rèn)是否需要驗(yàn)證字段:

use Illuminate\Validation\Rule;
Validator::make($request->all(), [  
  'role_id' => Rule::requiredIf($request->user()->is_admin),]);
  Validator::make($request->all(), [   
   'role_id' => Rule::requiredIf(function () use ($request) {     
      return $request->user()->is_admin;   
      }),
    ]);

required_unless:anotherfield,value,...

如果 anotherfield 字段不等于任一 value,驗(yàn)證的字段必須出現(xiàn)且不為空。

required_with:foo,bar,...

只有在其他任一指定字段出現(xiàn)時(shí),驗(yàn)證的字段才必須出現(xiàn)且不為空。

required_with_all:foo,bar,...

只有在其他指定字段全部出現(xiàn)時(shí),驗(yàn)證的字段才必須出現(xiàn)且不為空。

required_without:foo,bar,...

只在其他指定任一字段不出現(xiàn)時(shí),驗(yàn)證的字段才必須出現(xiàn)且不為空。

required_without_all:foo,bar,...

只有在其他指定字段全部不出現(xiàn)時(shí),驗(yàn)證的字段才必須出現(xiàn)且不為空。

same:field

驗(yàn)證的字段必須與給定字段匹配。

size:value

驗(yàn)證的字段必須具有與給定值匹配的大小。對(duì)于字符串,value 對(duì)應(yīng)字符數(shù)。對(duì)于數(shù)字,value 對(duì)應(yīng)給定的整數(shù)值。對(duì)于數(shù)組,size 對(duì)應(yīng)數(shù)組的 count 值。對(duì)于文件,size 對(duì)應(yīng)文件大?。▎挝?kb)。

starts_with:foo,bar,...

驗(yàn)證的字段必須以給定值之一開頭。

string

驗(yàn)證的字段必須是一個(gè)字符串。如果允許這個(gè)字段為 null,需要給這個(gè)字段分配 nullable 規(guī)則。

timezone

驗(yàn)證的字段必須是一個(gè)基于 PHP 函數(shù)  timezone_identifiers_list 的有效時(shí)區(qū)標(biāo)識(shí)。

unique:table,column,except,idColumn

驗(yàn)證的字段在給定的數(shù)據(jù)庫(kù)表中必須是唯一的。如果沒有指定 column ,將會(huì)使用字段本身的名稱。

指定自定義字段

'email' => 'unique:users,email_address'

自定義數(shù)據(jù)庫(kù)連接

有時(shí),你可能需要為驗(yàn)證程序創(chuàng)建的數(shù)據(jù)庫(kù)查詢?cè)O(shè)置自定義連接。上面的例子中,將 unique:users 設(shè)置為驗(yàn)證規(guī)則,等于使用默認(rèn)數(shù)據(jù)庫(kù)連接來(lái)查詢數(shù)據(jù)庫(kù)。如果要對(duì)其進(jìn)行修改,請(qǐng)使用「點(diǎn)」方法指定連接和表名:

'email' => 'unique:connection.users,email_address'

強(qiáng)迫 Unique 規(guī)則忽略指定 ID :

有時(shí),你可能希望在進(jìn)行字段唯一性驗(yàn)證時(shí)忽略指定 ID 。例如, 在「更新個(gè)人資料」頁(yè)面會(huì)包含用戶名、郵箱和地點(diǎn)。這時(shí)你會(huì)想要驗(yàn)證更新的 E-mail 值是否唯一。如果用戶僅更改了用戶名字段而沒有改 E-mail 字段,就不需要拋出驗(yàn)證錯(cuò)誤,因?yàn)榇擞脩粢呀?jīng)是這個(gè) E-mail 的擁有者了。

使用 Rule 類定義規(guī)則來(lái)指示驗(yàn)證器忽略用戶的 ID。這個(gè)例子中通過數(shù)組來(lái)指定驗(yàn)證規(guī)則,而不是使用 | 字符來(lái)分隔:

use Illuminate\Validation\Rule;
Validator::make($data, [ 
   'email' => [      
     'required',        
     Rule::unique('users')->ignore($user->id),  
     ],
 ]);

{tip} 您永遠(yuǎn)不應(yīng)將任何用戶控制的請(qǐng)求輸入傳遞給 ignore 方法。相反,您應(yīng)該只從 Eloquent 模型實(shí)例傳遞系統(tǒng)生成的唯一 ID,例如自增 ID 或 UUID。否則,您的應(yīng)用程序?qū)⑷菀资艿?SQL 注入攻擊。

你可以傳遞整個(gè)模型實(shí)例,而不是將模型鍵的值傳遞給 ignore 方法。Laravel 將自動(dòng)從模型中提取主鍵:

Rule::unique('users')->ignore($user)

如果你的數(shù)據(jù)表使用的主鍵名稱不是 id ,那就在調(diào)用 ignore 方法時(shí)指定字段的名稱:

Rule::unique('users')->ignore($user->id, 'user_id')

默認(rèn)情況下,unique 規(guī)則將檢查與要驗(yàn)證的屬性的名稱匹配的列是否唯一。但是你可以將不同的列名稱作為第二個(gè)參數(shù)傳遞給 unique 方法:

Rule::unique('users', 'email_address')->ignore($user->id),

增加額外的 Where 語(yǔ)句:

你也可以通過 where 方法指定額外的查詢條件。例如, 我們添加 account_id1 的約束:

'email' => Rule::unique('users')->where(function ($query) {  
  return $query->where('account_id', 1);
})

url

驗(yàn)證的字段必須是有效的 URL。

uuid

驗(yàn)證字段必須是有效的 RFC 4122(版本 1,3,4 或 5)通用唯一標(biāo)識(shí)符(UUID)。

按條件增加規(guī)則

存在時(shí)則驗(yàn)證

在某些情況下,只有在該字段存在于數(shù)組中時(shí), 才可以對(duì)字段執(zhí)行驗(yàn)證檢查??赏ㄟ^增加 sometimes 到規(guī)則列表來(lái)實(shí)現(xiàn):

$v = Validator::make($data, [    'email' => 'sometimes|required|email',]);

在上面的例子中, email 字段只有在 $data 數(shù)組中存在才會(huì)被驗(yàn)證。

{tip} 如果你嘗試驗(yàn)證應(yīng)該始終存在但可能為空的字段,請(qǐng)查閱 可選字段的注意事項(xiàng)

復(fù)雜的條件驗(yàn)證

有時(shí)候你可能需要增加基于更復(fù)雜的條件邏輯的驗(yàn)證規(guī)則。例如,你可以希望某個(gè)指定字段在另一個(gè)字段的值超過 100 時(shí)才為必填?;蛘弋?dāng)某個(gè)指定字段存在時(shí),另外兩個(gè)字段才能具有給定的值。增加這樣的驗(yàn)證條件并不難。首先,使用 靜態(tài)規(guī)則 創(chuàng)建一個(gè) Validator 實(shí)例:

$v = Validator::make($data, [  
  'email' => 'required|email',    
  'games' => 'required|numeric',
]);

假設(shè)我們有一個(gè)專為游戲收藏家所設(shè)計(jì)的網(wǎng)頁(yè)應(yīng)用程序。如果游戲收藏家收藏超過一百款游戲,我們會(huì)希望他們來(lái)說(shuō)明下為什么他們會(huì)擁有這么多游戲。比如說(shuō)他們有可能經(jīng)營(yíng)了一家游戲分銷商店,或者只是為了享受收集的樂趣。為了在特定條件下加入此驗(yàn)證需求,可以在 Validator 實(shí)例中使用 sometimes 方法。

$v->sometimes('reason', 'required|max:500', function ($input) {  
  return $input->games >= 100;
});

傳入 sometimes 方法的第一個(gè)參數(shù)是要用來(lái)驗(yàn)證的字段名稱。第二個(gè)參數(shù)是我們想使用的驗(yàn)證規(guī)則。 閉包 作為第三個(gè)參數(shù)傳入,如果其返回 true , 則額外的規(guī)則就會(huì)被加入。這個(gè)方法可以輕松地創(chuàng)建復(fù)雜的條件驗(yàn)證。你甚至可以一次對(duì)多個(gè)字段增加條件驗(yàn)證:

$v->sometimes(['reason', 'cost'], 'required', function ($input) {   
   return $input->games >= 100;
 });

{tip} 傳入 閉包$input 參數(shù)是 Illuminate\Support\Fluent 的一個(gè)實(shí)例,可用來(lái)訪問你的輸入或文件對(duì)象。

驗(yàn)證數(shù)組

驗(yàn)證表單的輸入為數(shù)組的字段也不難。你可以使用 「點(diǎn)」方法來(lái)驗(yàn)證數(shù)組中的屬性。例如,如果傳入的 HTTP 請(qǐng)求中包含 photos[profile] 字段, 可以如下驗(yàn)證:

$validator = Validator::make($request->all(), [  
  'photos.profile' => 'required|image',
]);

你也可以驗(yàn)證數(shù)組中的每個(gè)元素。例如,要驗(yàn)證指定數(shù)組輸入字段中的每一個(gè) email 是唯一的,可以這么做:

$validator = Validator::make($request->all(), [  
  'person.*.email' => 'email|unique:users',    
  'person.*.first_name' => 'required_with:person.*.last_name',
]);

同理,你可以在語(yǔ)言文件定義驗(yàn)證信息時(shí)使用 * 字符,為基于數(shù)組的字段使用單個(gè)驗(yàn)證消息:

'custom' => [  
  'person.*.email' => [    
      'unique' => 'Each person must have a unique e-mail address',   
     ]
    ],

自定義驗(yàn)證規(guī)則

使用規(guī)則對(duì)象

Laravel 提供了許多有用的驗(yàn)證規(guī)則;同時(shí)也支持自定義規(guī)則。注冊(cè)自定義驗(yàn)證規(guī)則的方法之一,就是使用規(guī)則對(duì)象。可以使用 Artisan 命令 make:rule 來(lái)生成新的規(guī)則對(duì)象。接下來(lái),讓我們用這個(gè)命令生成一個(gè)驗(yàn)證字符串是大寫的規(guī)則。Laravel 會(huì)將新的規(guī)則存放在 app/Rules 目錄中:

php artisan make:rule Uppercase

一旦創(chuàng)建了規(guī)則,我們就可以定義它的行為。規(guī)則對(duì)象包含兩個(gè)方法: passesmessagepasses 方法接收屬性值和名稱,并根據(jù)屬性值是否符合規(guī)則而返回  truefalse。 message 方法應(yīng)返回驗(yàn)證失敗時(shí)應(yīng)使用的驗(yàn)證錯(cuò)誤消息:

<?php
  namespace App\Rules;
  use Illuminate\Contracts\Validation\Rule;
  class Uppercase implements Rule{   
        /**
     * 判斷驗(yàn)證規(guī)則是否通過。
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */   
    public function passes($attribute, $value)   
     {       
       return strtoupper($value) === $value;   
      }   
     /**
     * 獲取驗(yàn)證錯(cuò)誤消息。
     *
     * @return string
     */   
    public function message()  
      {       
       return 'The :attribute must be uppercase.';   
       }
      }

當(dāng)然, 如果你希望從翻譯文件中返回一個(gè)錯(cuò)誤消息,你可以從 message 方法中調(diào)用輔助函數(shù) trans

/**
 * 獲取驗(yàn)證錯(cuò)誤消息。
 *
 * @return string
 */
 public function message(){  
   return trans('validation.uppercase');
  }

一旦規(guī)則對(duì)象被定義好后,你可以通過將規(guī)則對(duì)象的實(shí)例和其他驗(yàn)證規(guī)則一起來(lái)傳遞給驗(yàn)證器:

use App\Rules\Uppercase;$request->validate([  
  'name' => ['required', 'string', new Uppercase],
]);

使用閉包

如果你在應(yīng)用程序中只需要一次自定義規(guī)則的功能,則可以使用閉包而不是規(guī)則對(duì)象。閉包接收屬性的名稱,屬性的值如果驗(yàn)證失敗則應(yīng)該使用回調(diào)中的 $fail

$validator = Validator::make($request->all(), [   
 'title' => [      
   'required',        
   'max:255',        
   function ($attribute, $value, $fail) {          
     if ($value === 'foo') {              
       $fail($attribute.' is invalid.');      
             }      
            },    
          ],
        ]);

使用擴(kuò)展

注冊(cè)自定義的驗(yàn)證規(guī)則的另一種方法是使用 Validator facade 中的 extend 方法。讓我們?cè)?服務(wù)容器 中使用這個(gè)方法來(lái)注冊(cè)自定義驗(yàn)證規(guī)則:

<?php
  namespace App\Providers;
  use Illuminate\Support\ServiceProvider;
  use Illuminate\Support\Facades\Validator;
  class AppServiceProvider extends ServiceProvider{   
      /**
     * 引導(dǎo)任何應(yīng)用程序。
     *
     * @return void
     */   
  public function boot()   
   {       
     Validator::extend('foo', function ($attribute, $value, $parameters, $validator) { 
        return $value == 'foo';  
         });   
       }    
     /**
     * 注冊(cè)服務(wù)提供器。
     *
     * @return void
     */   
     public function register()   
      {       
       //   
       }
     }

自定義的驗(yàn)證閉包接收四個(gè)參數(shù):要被驗(yàn)證的屬性名稱 $attribute、屬性的值 $value、傳入驗(yàn)證規(guī)則的參數(shù)數(shù)組 $parameters 、以及 Validator 實(shí)列。

除了使用閉包,你也可以傳入類和方法到 extend 方法中:

Validator::extend('foo', 'FooValidator@validate');

定義錯(cuò)誤消息

你還需要為自定義規(guī)則定義錯(cuò)誤信息。你可以使用內(nèi)聯(lián)自定義消息數(shù)組或者在驗(yàn)證語(yǔ)言文件中添加條目來(lái)實(shí)現(xiàn)這一功能。 消息應(yīng)該被放到數(shù)組的第一位, 而不是在只用于存放屬性指定錯(cuò)誤信息的 custom 數(shù)組內(nèi):

"foo" => "Your input was invalid!",
"accepted" => "The :attribute must be accepted.",
// 其余的驗(yàn)證錯(cuò)誤消息...

當(dāng)創(chuàng)建一個(gè)自定義驗(yàn)證規(guī)則時(shí),你可能有時(shí)候需要為錯(cuò)誤信息定義自定義占位符??梢酝ㄟ^創(chuàng)建自定義驗(yàn)證器然后調(diào)用 Validator 門面上的  replacer 方法。你可以在 服務(wù)容器 的 boot 方法中執(zhí)行如下操作:

/**
 * 啟動(dòng)應(yīng)用程序。
 *
 * @return void
 */
 public function boot(){  
   Validator::extend(...);    
   Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {    
       return str_replace(...);  
      });
 }

隱式擴(kuò)展

默認(rèn)情況下, 當(dāng)所要驗(yàn)證的屬性不存在或包含由  required 規(guī)則定義的空值時(shí),那么正常的驗(yàn)證規(guī)則,包括自定義擴(kuò)展將不會(huì)執(zhí)行。 例如,unique 規(guī)則將不會(huì)檢驗(yàn) null 值:

$rules = ['name' => 'unique'];
$input = ['name' => null];
Validator::make($input, $rules)->passes();
 // true

如果要求即使為空時(shí)也要驗(yàn)證屬性,則必須要暗示屬性是必須的。要?jiǎng)?chuàng)建這樣一個(gè)「隱式」擴(kuò)展, 可以使用 Validator::extendImplicit() 方法:

Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) { 
   return $value == 'foo';
  });

{note} 「隱式」擴(kuò)展只暗示該屬性是必需的。至于它到底是缺失的還是空值這取決于你。

本文章首發(fā)在 LearnKu.com 網(wǎng)站上。