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

表單驗證

表單驗證


表單驗證

簡介

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

快速驗證

要了解 Laravel 強大的驗證功能,讓我們看一個驗證表單并將錯誤消息顯示回給用戶的完整示例。

定義路由

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

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

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

創(chuàng)建路由器

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

<?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)   
     {      
       // 驗證并存儲博客文章...   
      }
   }

編寫驗證器邏輯

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

讓我們接著回到 store 方法來深入理解 validate 方法:

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

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

首次驗證失敗后停止運行

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

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

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

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

如果你的 HTTP 請求包含一個 「嵌套」 參數(shù)(即數(shù)組),那你可以在驗證規(guī)則中通過 「點」 語法來指定這些參數(shù)。

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

顯示驗證錯誤信息

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

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

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

在上面的例子中,當驗證失敗的時候,用戶將會被重定向到控制器的 create 方法,使我們能在視圖中顯示錯誤信息:

<!-- /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)于可選字段的注意事項

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

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

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

AJAX 請求 & 驗證

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

驗證表單請求

創(chuàng)建表單請求驗證

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

php artisan make:request StoreBlogPost

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

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

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

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

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

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

添加表單請求后鉤子

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

/**
 *  配置驗證器實例。
 *
 * @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!');        
             }   
         });
   }

表單請求授權(quán)驗證

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

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

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

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

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

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

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

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

自定義錯誤消息

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

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

自定義驗證屬性

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

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

手動創(chuàng)建驗證器

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

<?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 方法的第一個參數(shù)是需要驗證的數(shù)據(jù)。第二個參數(shù)則是該數(shù)據(jù)的驗證規(guī)則。

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

自動重定向

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

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

命名錯誤包

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

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

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

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

驗證后鉤子

驗證器還允許你添加在驗證成功之后允許的回調(diào)函數(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()) {  
   //
 }

處理錯誤消息

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

查看特定字段的第一個錯誤信息

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

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

查看特定字段的所有錯誤消息

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

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

如果要驗證表單的數(shù)組字段,你可以使用 * 來獲取每個數(shù)組元素的所有錯誤消息:

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

查看所有字段的所有錯誤消息

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

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

判斷特定字段是否含有錯誤消息

has 方法可以被用來判斷給定的字段是否存在錯誤信息:

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

自定義錯誤消息

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

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

在這個例子中,:attribute 占位符會被驗證字段的實際名稱取代。除此之外,你還可以在驗證消息中使用其它占位符。例如:

$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',
];

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

有時候你可能只想為特定的字段自定義錯誤消息。只需在屬性名稱后使用「點」語法來指定驗證的規(guī)則即可:

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

在語言文件中指定自定義消息

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

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

在語言文件中指定自定義屬性

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

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

在語言文件中指定自定義值

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

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

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

    當payment type為cc時,credit card number 不能為空。

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

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

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

    當payment type 為信用卡時,credit card number不能為空。

可用驗證規(guī)則

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

accepted

驗證字段必須是 yes, on, 1,或 true。這在確認「服務(wù)條款」是否同意時相當有用。

active_url

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

after:date

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

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

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

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

after_or_equal:date

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

alpha

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

alpha_dash

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

alpha_num

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

array

驗證的字段必須是一個 PHP 數(shù)組。

bail

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

before:date

驗證字段必須是在給定日期之前。這個日期值將會被傳遞給  PHP 的  strtotime 函數(shù)來計算。

before_or_equal:date

驗證字段必須是在給定日期之前或與之相同的日期。這個日期值將會被傳遞給  PHP 的  strtotime 函數(shù)來計算。

between:min,max

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

boolean

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

confirmed

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

date

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

date_equals:date

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

date_format:format

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

different:field

驗證字段必須具有與 field 不同的值。

digits:value

驗證字段必須為 numeric ,且必須具有_value_的確切長度。

digits_between:min,max

驗證的字段的長度必須在給定的  min 和  max 之間。

dimensions

驗證中的文件必須是圖片,并且符合指定的規(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 的表達式 或者一個浮點數(shù),像 1.5 來指定:

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

由于此規(guī)則需要多個參數(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

當驗證數(shù)組時,驗證字段不得包含任何重復(fù)值。

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

email

驗證字段必須為正確格式的電子郵件地址。

exists:table,column

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

Exists 規(guī)則基本用法

'state' => 'exists:states'

如果未指定 column 選項,則將使用字段名稱。

指定自定義的表字段

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

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

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

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

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

file

驗證的字段必須是成功上傳的文件。

filled

驗證字段存在時不得為空。

gt:field

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

gte:field

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

image

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

in:foo,bar,...

驗證字段必須包含在給定的值列表中。由于此規(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

驗證的字段必須存在于另一個字段 anotherfield 的值中。

integer

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

ip

驗證的字段必須是 IP 地址。

ipv4

驗證的字段必須是 IPv4 地址。

ipv6

驗證的字段必須是 IPv6 地址。

json

驗證的字段必須是有效的 JSON 字符串。

lt:field

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

lte:field

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

max:value

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

mimetypes:text/plain,...

驗證的文件必須與給定 MIME 類型之一匹配:

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

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

mimes:foo,bar,...

驗證的文件必須具有與列出的其中一個擴展名相對應(yīng)的 MIME 類型。

MIME 規(guī)則基本用法

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

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

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

min:value

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

not_in:foo,bar,...

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

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

not_regex:pattern

驗證中的字段必須與給定的正則表達式不匹配。

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

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

nullable

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

numeric

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

present

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

regex:pattern

驗證的字段必須與給定的正則表達式匹配。

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

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

required

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

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

required_if:anotherfield,value,...

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

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

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,驗證的字段必須出現(xiàn)且不為空。

required_with:foo,bar,...

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

required_with_all:foo,bar,...

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

required_without:foo,bar,...

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

required_without_all:foo,bar,...

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

same:field

驗證的字段必須與給定字段匹配。

size:value

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

starts_with:foo,bar,...

驗證的字段必須以給定值之一開頭。

string

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

timezone

驗證的字段必須是一個基于 PHP 函數(shù)  timezone_identifiers_list 的有效時區(qū)標識。

unique:table,column,except,idColumn

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

指定自定義字段

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

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

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

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

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

有時,你可能希望在進行字段唯一性驗證時忽略指定 ID 。例如, 在「更新個人資料」頁面會包含用戶名、郵箱和地點。這時你會想要驗證更新的 E-mail 值是否唯一。如果用戶僅更改了用戶名字段而沒有改 E-mail 字段,就不需要拋出驗證錯誤,因為此用戶已經(jīng)是這個 E-mail 的擁有者了。

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

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

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

你可以傳遞整個模型實例,而不是將模型鍵的值傳遞給 ignore 方法。Laravel 將自動從模型中提取主鍵:

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

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

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

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

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

增加額外的 Where 語句:

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

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

url

驗證的字段必須是有效的 URL。

uuid

驗證字段必須是有效的 RFC 4122(版本 1,3,4 或 5)通用唯一標識符(UUID)。

按條件增加規(guī)則

存在時則驗證

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

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

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

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

復(fù)雜的條件驗證

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

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

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

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

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

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

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

驗證數(shù)組

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

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

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

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

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

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

自定義驗證規(guī)則

使用規(guī)則對象

Laravel 提供了許多有用的驗證規(guī)則;同時也支持自定義規(guī)則。注冊自定義驗證規(guī)則的方法之一,就是使用規(guī)則對象??梢允褂?Artisan 命令 make:rule 來生成新的規(guī)則對象。接下來,讓我們用這個命令生成一個驗證字符串是大寫的規(guī)則。Laravel 會將新的規(guī)則存放在 app/Rules 目錄中:

php artisan make:rule Uppercase

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

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

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

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

一旦規(guī)則對象被定義好后,你可以通過將規(guī)則對象的實例和其他驗證規(guī)則一起來傳遞給驗證器:

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

使用閉包

如果你在應(yīng)用程序中只需要一次自定義規(guī)則的功能,則可以使用閉包而不是規(guī)則對象。閉包接收屬性的名稱,屬性的值如果驗證失敗則應(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.');      
             }      
            },    
          ],
        ]);

使用擴展

注冊自定義的驗證規(guī)則的另一種方法是使用 Validator facade 中的 extend 方法。讓我們在 服務(wù)容器 中使用這個方法來注冊自定義驗證規(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';  
         });   
       }    
     /**
     * 注冊服務(wù)提供器。
     *
     * @return void
     */   
     public function register()   
      {       
       //   
       }
     }

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

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

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

定義錯誤消息

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

"foo" => "Your input was invalid!",
"accepted" => "The :attribute must be accepted.",
// 其余的驗證錯誤消息...

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

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

隱式擴展

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

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

如果要求即使為空時也要驗證屬性,則必須要暗示屬性是必須的。要創(chuàng)建這樣一個「隱式」擴展, 可以使用 Validator::extendImplicit() 方法:

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

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

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