驗證
簡介
Laravel 對驗證應用的輸入數據提供了多中途徑的實現。默認的,Laravel 的基礎控制器類使用了 ValidatesRequests
trait,該性狀允許使用各種強大的驗證約束來驗證 HTTP 的輸入請求。
快速入門
要了解 Laravel 強大的驗證功能,我們需要一個完整的示例來描述表單的驗證,和將表單驗證的錯誤信息顯示給用戶。
定義路由
首先,讓我們假定我們在 app/Http/routes.php
文件中擁有下述的路由:
// Display a form to create a blog post...
Route::get('post/create', 'PostController@create');
// Store a new blog post...
Route::post('post', 'PostController@store');
當然, GET
路由會為用戶創建一個新的博客文章時提供一個表單,而 POST
路由會存儲新的博客文章到數據庫。
創建控制器
接著,我們需要一個控制器來處理這些路由,目前,我們先不在 store
方法里放任何的邏輯:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PostController extends Controller
{
/**
* Show the form to create a new blog post.
*
* @return Response
*/
public function create()
{
return view('post.create');
}
/**
* Store a new blog post.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// Validate and store the blog post...
}
}
編寫驗證邏輯
現在我們準備好了在 store
方法中進行博客文章的驗證邏輯。如果你檢查應用的基礎控制器(App\Http\Controllers\Controller
) 類,你會發現該類使用了 ValidatesRequests
trait。這個性狀為所有的控制器提供了方便的 validate
方法。
validate
方法接收 HTTP 輸入請求,并設置驗證約束。如果驗證約束通過,那么后續的代碼將會正常的執行。如果驗證失敗,那么將會拋出一個恰當的異常響應返回給用戶。對于傳統的 HTTP 請求,驗證器會自動生成一個重定向響應,而 AJAX 請求,則會返回 JSON 響應。
為了能夠更好的理解 validate
方法,讓我們繼續回到 store
方法:
/**
* Store a new blog post.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid, store in database...
}
就如你所看到的,我們簡單的傳遞了一個 HTTP 輸入請求,并且在 validate
方法中設置了預期的驗證約束。而這次,如果驗證失敗,那么相應的響應會被自動的生成并且被返回給請求用戶。如果驗證通過,那么我們的控制器會繼續執行之后的業務。
在初次驗證失敗時停止
有時候你希望在獲取首個驗證約束失敗時停止當前屬性其余約束的驗證。你可以在屬性中加入 bail
約束:
$this->validate($request, [
'title' => 'bail|required|unique:posts|max:255',
'body' => 'required',
]);
在這個例子中,如果 title
屬性中的 required
約束驗證失敗,那么 unique
約束就不會再被驗證。約束是按照其被分配的順序來進行驗證的。
嵌套的屬性
如果你的 HTTP 請求包含了嵌套的參數,你可以使用 .
語法來為其指定約束:
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'author.name' => 'required',
'author.description' => 'required',
]);
顯示驗證錯誤
那么,假如傳入的請求參數并沒有通過給定約束的驗證怎么辦?就如前面所提到的,Laravel 會自動的重定向用戶到之前的位置。另外,所有的驗證錯誤信息都會被自動的閃存到 session 中。
你需要注意到我們并沒有明確的綁定錯誤信息到 GET
路由的響應視圖里。這是因為 laravel 會檢查閃存 seesion 里的錯誤數據,并且會自動的在其可用時注入到視圖中。你可以在視圖中使用 $errors
變量,它是一個 Illuminate\Support\MessageBag
實例。如果需要了解更多這個實例對象,請參考其 文檔。
注意:
$errors
變量是通過Illuminate\View\Middleware\ShareErrorsFromSession
中間件來綁定到視圖中的。這個中間件已經被提供到了web
中間件組中。這個中間件被應用時會自主的在你的視圖中注入$errors
變量,這允許你方便的假定$errors
變量總是已經被定義且可以安全的使用。
所以,在我們的例子中,當驗證失敗是,用戶將會被重定向到控制器的 create
方法中,這允許你在視圖中展示錯誤信息:
<!-- /resources/views/post/create.blade.php -->
<h1>Create Post</h1>
@if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!-- Create Post Form -->
自定義閃存錯誤格式
如果你希望在驗證失敗時可以自定義閃存進 session 中的錯誤消息的格式,你需要在你的基礎控制器中復寫 formatValidationErrors
方法。不要忘記在頂部引入 Illuminate\Contracts\Validation\Validator
類:
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
abstract class Controller extends BaseController
{
use DispatchesJobs, ValidatesRequests;
/**
* {@inheritdoc}
*/
protected function formatValidationErrors(Validator $validator)
{
return $validator->errors()->all();
}
}
AJAX 請求 & 驗證
在上面的示例中,我們使用傳統的表單來發送數據到應用,事實上,如今很多應用都使用 AJAX 請求,當通過 AJAX 請求來使用 validate
方法時,laravel 并不會自動生成重定向的響應,相反的,laravel 會生成一個包含了驗證錯誤消息的 JSON 響應。并且該響應會伴隨 422 HTTP 狀態碼。
驗證數組
驗證數組形式的輸入并不是一件痛苦的事情。比如,去驗證給定的輸入數組中所有的郵件都應該是唯一的,你可以參照如下做法:
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
同樣的,你也可以在使用語言文件來指定特定的驗證消息時使用 *
通配符。這可以輕而易舉的使用單條驗證消息提供給基于數組的輸入:
'custom' => [
'person.*.email' => [
'unique' => 'Each person must have a unique e-mail address',
]
]
其它驗證途徑
手動的創建 Validators
如果你不喜歡使用 ValidatesRequests
trait 的 validator
方法,你也可以通過使用 Validator
假面來創建一個 validator 實例。Validator
假面的 make
方法就可以生成一個新的 validator 實例:
<?php
namespace App\Http\Controllers;
use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PostController extends Controller
{
/**
* Store a new blog post.
*
* @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
方法所接受的第一個參數是需要被驗證的數據,第二個參數則是應該施加到數據的驗證約束。
如果請求的驗證失敗,那么你需要使用 withErrors
方法來講錯誤消息存放到 session 中。當使用該方法時,$errors
變量會在重定向之后被自動的共享到你的視圖中,這使你可以輕松的將錯誤信息展示給用戶。withErrors
方法可以接收 validator 實例,或者 MessageBag
實例,又或者原生的 PHP array
。
被命名的錯誤袋
如果你在一個獨立頁面中包含了多個表單。那么你可能會希望能對 MessageBag
進行命名以展示相應的表單錯誤。你可以直接在 withErrors
方法中傳遞第二個參數對其進行命名:
return redirect('register')
->withErrors($validator, 'login');
你之后可以通過 $errors
變量來訪問被命名的 MessageBag
實例:
{{ $errors->login->first('email') }}
驗證之后的 Hook
驗證器也允許你在驗證完成之后執行特定的操作。這允許你輕松的進行進一步的驗證,你也可以在消息集合里添加更多的錯誤消息。在驗證器的實例上使用 after
方法來進行 hook:
$validator = Validator::make(...);
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->ad('field', 'Something is wrong with this field!');
}
});
if ($validator->fails()) {
//
}
表單請求驗證
對于更為復雜的驗證場景,你或許希望構建一個“表單請求”。表單請求是一個自定義的請求類,并且它包含了所有的驗證邏輯。你可以使用 make:request
Artisan CLI 命令來創建一個表單請求類:
php artisan make:request StoreBlogPostRequest
被生成的類會被存儲在 app/Http/Requests
目錄。讓我們在 rules
方法中來添加一些驗證約束:
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
那么,這些驗證約束是如何被評定的?你所要做的所有的事情就是在你的控制器方法中添加該請求類的類型提示。傳入進來的表單請求會在控制器方法調用之前被自動的進行約束驗證,這意味著你完全不需要再你的控制器方法中添加任何的驗證邏輯:
/**
* Store the incoming blog post.
*
* @param StoreBlogPostRequest $request
* @return Response
*/
public function store(StoreBlogPostRequest $request)
{
// The incoming request is valid...
}
如果驗證失敗,用戶會被自動的重定向到他們之前的位置。那么驗證錯誤消息也會自動的閃存進 session 數據中被用于顯示。如果你使用的是 AJAX 請求,那么會自動的返回一個包含所有驗證錯誤消息的 JSON 格式的響應,它的 HTTP 狀態碼會被設置為 422。
授權表單請求
表單請求類也包含了 authorize
方法。在這個方法中,你可以檢查已認證的用戶是否真的擁有修改所給定資源的權利。比如,如果用戶嘗試修改博客文章中的評論消息,我們需要考慮一下這個評論是屬于他的嗎:
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
$commentId = $this->route('comment');
return Comment::where('id', $commentId)
->where('user_id', Auth::id())->exists();
}
你應該注意到了上述實例中的 route
方法的調用。這個方法用來在路由被訪問時發放所定義的 URL 參數,比如下面路由的 {comment}
參數:
Route::post('comment/{comment}');
如果 authorize
方法返回 false
,那么會響應一個 403 的狀態碼,并且控制器的方法不會被執行。
如果你計劃在應用的其它部分來處理授權邏輯,你可以簡單的在 authorize
方法中返回 true
:
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
自定義閃存的錯誤格式
如果你希望在驗證失敗時自定義閃存到 session 數據中驗證錯誤消息的格式,那么你需要復寫(App\Http\Requests\Request
)基礎請求類中的 formatErros
方法。不要忘記引入 Illuminate\Contracts\Validation\Validator
類:
/**
* {@inheritdoc}
*/
protected function formatErrors(Validator $validator)
{
return $validator->errors()->all();
}
自定義錯誤消息
你也可以通過在請求類中復寫 messages
方法來自定義錯誤消息。該方法應該返回一個包含相應錯誤消息的鍵值對數組:
/**
* Get the error messages for the defined validation rules.
*
* @return array
*/
public function message()
{
return [
'title.required' => 'A title is required',
'body.required' => 'A message is required',
];
}
與錯誤消息協作
在調用 Validator
實例的 errors
方法之后,你可以檢索到一個 Illuminate\Support\MessageBag
的實例,這實例擁有多種便捷的方法來與錯誤消息進行交互。
檢索給定字段中的首個錯誤消息
你可以使用 first
方法來檢索給定字段的首個錯誤消息:
$message = $validator->errors();
echo $message->first('email');
檢索給定字段的所有錯誤消息
如果你需要檢索給定字段的所有消息所組成的數組,那么你應該使用 get
方法:
foreach ($messages->get('email') as $message) {
//
}
檢索所有字段的所有錯誤消息
你可以使用 all
方法來檢索所有字段的所有錯誤消息所組成的數組:
foreach ($message->all() as $message) {
//
}
判斷所給定的字段中是否存在消息
if ($messages->has('email')) {
//
}
使用給定的格式來檢索獲取錯誤消息
echo $message->first('email', '<p>:message</p>');
使用給定的格式來檢索所有的錯誤消息
foreach ($messages->all('<li>:message</li>') as $message) {
//
}
自定義錯誤消息
如果你需要,你可以使用自定義的錯誤消息來取代默認的驗證消息。這里有幾種方式來指定自定義的消息。首先,你可以傳遞自定的消息作為 Validator::make
方法的第三個參數:
$messages = [
'required' => 'The :attribute field is required.',
];
$validator = Validator::make($input, $rules, $messages);
在這個例子中,:attribute
占位符會被驗證數據中真實的名稱所替換。你還可以利用其它的占位符到驗證消息中,比如:
$message = [
'same' => 'The :attribute and :other must match.',
'size' => 'The :attribute must be exactly :size.',
'between' => 'The :attribute must be between :min - :max.',
'in' => 'The :attribute must be one of the following types: :values',
];
為給定的屬性指定錯誤消息
有時候,你可能希望指定自定義的錯誤消息到特定的字段。你可以使用 .
符號來進行分割,屬性名應該在前,約束應該在后:
$message = [
'email.required' => 'We need to know your e-mail address!',
];
在語言文件中指定自定義消息
在多數情況下,你可能希望使用一個語言文件中的自定義消息屬性直接傳遞到 Validator
。你可以在 resources/lang/xx/validation.php
語言文件中添加 custom
數組來存儲你的消息:
'custom' => [
'email' => [
'required' => 'We need to know your e-mail address!',
],
],
可用的驗證約束
下面是所有的可用的驗證約束和它們的功能的列表:
accepted
驗證的字段必須為 yes,on,1,或者 true。這通常用來驗證服務條款的承諾。
active_url
驗證的字段必須可以通過 checkdnsrr
PHP 方法的驗證。
after:date
驗證的字段必須是給定日期之后的值。日期會被傳遞到 strtotime
PHP 方法:
`start_date' => 'required|date|after:tomorrow'
你也可以指定使用其它字段的日期來進行評估:
'finish_date' => 'required|date|after:start_date'
alpha
驗證的字段必須全部是由字母字符組成的字符串。
alpha_dash
驗證的字段可以是字母,數字,-,_ 所組成的字符串。
alpha_num
驗證的字段必須全部由字母或數字所組成。
array
驗證的字段必須是一個 PHP array
。
before:date
驗證的字段的值必須比指定的日期要早。指定的日期會被傳遞到 PHP 的 strtotime
方法。
between:min,max
驗證的字段的大小必須在給定的 min 和 max 之間。字符串,數字和文件都會使用和 size
約束的相同的評估方式。
boolean
驗證的字段必須能夠轉換為布爾值。所接受的輸入可以是 true
,false
,1
,0
,"1"
,"0"
。
confirmed
驗證的字段必須能夠和 foo_confirmation
字段相匹配。比如,如果驗證的字段是 password
,相應的 password_confirmation
字段必須在輸入中被提供且與 password
相匹配。
date
驗證的字段必須是一個有效的日期,它應該能被 strtotime
PHP 方法通過。
date_format:format
驗證的字段必須匹配給定的格式。該格式會被 PHP date_parse_from_format
方法評定,你應該只使用 date
或者 date_format
其中之一來進行驗證字段,不要全部都使用。
different:field
驗證的字段必須與給定的字段不同。
digits:value
驗證的字段必須是數字類型并且具有指定的長度。
digits_between:min,max
驗證的字段必須具有指定區間的長度。
dimensions
驗證的字段必須是一個圖片類型的,并且要求符合指定的參數約束:
'avatar' => 'dimensions:min_with=100,min_height=200'
可用的參數有:min_width,max_width,min_height,max_height,width,height,ratio。
distinct
當與數組協作時,驗證的字段中必須不能含有重復的值:
'foo.*.id' => 'distinct'
驗證的字段必須是一個郵件地址的格式。
exists:table,column
驗證的字段必須能在指定數據庫表中檢索的到。
Exists 基礎約束用法
'state' => 'exists:states'
指定自定義列名稱
'state' => 'exists:states,abbreviation'
你也可以像使用 where
語句一樣指定添加更多的查詢條件:
'email' => 'exists:staff,email,account_id,1'
查詢條件也可以使用 !
來表明否定值:
'eamil' => 'exists:staff,email,role,!admin'
你也可以傳遞 NULL
或者 NOT_NULL
到查詢語句中:
'eamil' => 'exists:staff,email,deleted_at,NULL'
'eamil' => 'exists:staff,email,deleted_at,NOT_NULL'
極個別的情況下,你可能需要在 exists
查詢下指定特定的數據庫連接。你可以使用 .
語法將數據庫連接名前置來進行指定:
'email' => 'exists:connection.staff,email'
filled
驗證的字段如果出現,那么它一定不能為空值。
image
被驗證的文件必須是一個圖片類型(jpeg,png,bmp,gif,svg)
in:foo,bar,...
驗證的字段必須是給定值列中的一個。
in_array:anotherfield
驗證的字段必須是指定的字段中值列之一。
integer
驗證的字段必須是一個整數。
ip
驗證的字段必須是一個 IP 地址。
json
驗證的字段必須是合法的 JSON 字符串
max:value
驗證的字段必須小于等于指定值。字符串,數字,和文件類型會與 size
約束使用相同的評估方法。
mimetypes:text/plain,...
驗證的字段必須匹配給定的 MIME 類型:
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'
為了判斷所上傳文件的 MIME 類型,laravel 會讀取文件的內容并且會嘗試猜測文件的 MIME 類型,這可能會與客戶端提供的文件 MIME 類型有所區別。
mimes:foo,bar,...
驗證的文件的 MIME 類型相應的后綴必須是所列的值之一。
基礎用法
'photo' => 'mimes:jpeg,bmp,png'
你只需要指定文件的擴展,這個約束會針對文件的內容進行猜測文件的 MIME 類型,然后進行擴展驗證。
完整的 MIME 類型和其相應的擴展后綴,你可以從 這里 找到。
min:value
驗證的字段必須比指定的值要小。字符串,數字和文件類型會使用 size
約束相同的評估方法。
not_in:foo,bar,...
驗證的字段不應該包含在給定的值列中。
numeric
驗證的字段必須是一個數值類型。
present
驗證的字段必須要求被提供,但是可以為空。
regex:pattern
驗證的字段必須與給定的正則表達式相匹配。
注意:當使用
regex
模式時,你必須將約束放進數組里來取代管道符分隔,特別是在正則表達式中包含管道符時。
required
驗證的字段必須被提供并且不能為空值。判斷空值的依據:
- 值是
null
- 值是空字符串
- 值是一個空數組或者空的
Countable
對象 - 值是一個沒有傳遞路徑的上傳的文件
required_if:anotherfield,value,...
驗證的字段必須在以下情況下被提供:指定的字段等于任意列出的值。
required_unless:anotherfield,value,...
驗證的字段必須在以下情況下被提供: 所指定的字段和所提供的值都不相等。
required_with:foo,bar,...
驗證的字段只有在其它所指定字段之一被提供時才會被要求提供。
required_with_all:foo,bar,...
驗證的字段只有在其它所指定字段全部被提供時才會被要求提供。
required_without:foo,bar,...
驗證的字段只有在其它所指定字段之一沒有被提供時被要求提供。
required_without_all:foo,bar,...
驗證的字段只有在所指定字段全部沒有被提供時才會被要求提供。
same:field
所驗證的字段必須與指定的字段相匹配。
size:value
驗證的字段必須具有給定值的大小。對于字符串數據,值應該是字符串的字符長度。對于數值數據,值應該是相應的整數值。對于數組,大小匹配數組的 count
大小。對于文件,應該匹配文件的字節大小。
string
驗證的字段必須是一個字符串。
timezone
驗證的字段必須是經過 PHP timezone_identifiers_list
方法驗證的合法的 timezone 標識。
unique:table,column,except,idColumn
驗證的字段必須在給定的數據表中唯一,如果 column
選型沒有被指定,那么會直接使用字段的名字。
指定自定義的列名
'email' => 'unique:users,email_address'
自定義數據庫連接
極少數情況下,你可能需要指定自定義的數據庫連接來進行驗證。就如上面所看到的,設置 unique:users
會使用默認的數據庫連接來進行約束驗證。如果想指定其他數據庫連接,你可以使用 .
語法并前置指定數據庫連接:
'email' => 'unique:connection.users,email_address'
強迫 Unique 約束 忽略給定的 ID
有時候,你可能會希望 unique 檢查忽略給定的 ID。比如,考慮一下一個更新個人信息的場景,它應該提供用戶的名稱,郵箱地址,和位置。你可能會想要驗證郵箱的唯一性。但是你只想驗證與用戶的當前郵箱不一致的郵箱的唯一性。也就是說你只想驗證這個郵箱有沒有被其他用戶所使用。你需要傳遞 ID 作為第三個參數來通知 unique 約束來忽略當前用戶的 ID:
'email' => 'unique:users,email_address,'.$user->id
如果表名使用的主鍵列名不是 id
,那么你還需要指定主鍵的列名到第四個參數:
'email' => 'unique:users,email_address,'.$user->id.',user_id'
添加額外的條件查詢
你也可以指定更多的條件查詢:
'email' => 'unique:users,email_address,null,id,account_id,1'
在上面的約束中,只有 account_id
為 1
的行會被約束進行檢查。
url
驗證的字段必須符合 PHP filter_var
方法驗證的有效 URL。
添加約束條件
在一些場景中,你會希望只有字段出現在了輸入數組中時才會對其進行驗證。你可以在約束列中添加 sometimes
約束來快速的完成指定:
$v = Validator::make($data, [
'email' => 'sometimes|required|email',
]);
這上面的例子中,只有 $data
中提供了 email
字段,email
的約束才會對其進行驗證。
復雜的驗證條件
有時候,你可能會希望基于更復雜的條件邏輯去進行約束的驗證。比如,你希望只有另外一個字段擁有比 100 更大的值時才會驗證給定的字段是否被提供。又或者你想要在只有另外一個字段被提供時才會需要其他兩個字段的值。添加這些條件判定并非是痛苦的一件事。首先,你還是需要創建一個 Validator
實例和一些靜態的約束:
$v = Validator::make($data, [
'email' => 'required|email',
'games' => 'required|numeric'
]);
讓我們假定我們的應用是服務于一些游戲收藏家的。如果一個游戲收藏家注冊了我們的應用,并且它們添加了超過 100 個游戲時。我們需要它們解釋一下為什么他會擁有那么多的游戲。比如,或許他開了一個游戲販賣超市,又或者他僅僅就是喜歡收藏。我們可以使用 Validator
實例上的 sometimes
方法來添加這個必要的條件:
$v->sometimes('reason', 'required|max:500', function ($input) {
return $input->games >= 100;
});
傳遞到 sometimes
方法的第一個參數是我們需要考慮驗證的字段的名字。第二個參數是我們想要添加的約束。如果第三個參數傳遞的 Closure
返回的結果是 true
,那么這個約束就會被添加進去。這就可以輕松的對復雜的驗證場景進行條件的構建。你甚至可以一次性的添加多個字段的條件驗證:
$v->sometimes(['reson', 'cost'], 'required', function ($input) {
return $input->games >= 100;
});
注意:傳遞到
Closure
中的$input
是一個Illuminate\Support\Flument
實例,并且它可以被用來訪問你的輸入和文件。
自定義驗證約束
Laravel 提供了各種有用的驗證約束。但是,你可能希望添加你自己的特定的約束。你可以使用 Validator
假面的 extend
方法來注冊自己的驗證約束。讓我們在服務提供者里注冊一個自定義的驗證約束:
<?php
namespace App\Providers;
use Validator;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
return $value == 'foo';
});
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}
自定義的驗證閉包中接收四個參數:需要被驗證的屬性名稱,屬性的值,一個需要被傳遞到約束的 $paramters
數組,和 Validator
實例。
你也可以傳遞一個類名和方法到 extend
方法中來代替閉包:
Validator::extend('foo', 'FooValidator@validate');
定義錯誤消息
你也需要為你的自定義約束添加一個錯誤消息。你可以使用行內自定義錯誤消息或者將其添加到獨立的驗證語言文件中。這個消息應該被存放在數組的一維中,而不是包含在 custom
數組里:
"foo" => 'Your input was invalid!',
'accepted' => 'The :attribute must be accepted.',
// The rest of the validation error messages...
當構建自定義的驗證約束時,你或許有時候也想為錯誤消息定義一些占位符。你可以使用 Validator
假面的 replacer
方法來進行占位替換。你可以在服務提供者的 boot
方法中來做這些:
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Validator::extend(...);
Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {
return str_replace(...);
});
}
隱式的擴展
默認的,當屬性被驗證時,如果在輸入數組中沒有被提供,或者驗證約束為 required
卻是一個空值。那么普通的驗證約束,包括自定義的約束擴展,都不會再執行。比如,unique
約束就不會在出現 null
值進行執行:
$rules = ['name' => 'unique'];
$input = ['name' => null];
Validator:make($input, $rules)->passes(); // true
如果需要約束即使是屬性值為空時也繼續執行,那么約束需要暗示屬性是必須的。你可以使用 Validator::extendImplicit()
方法來構建一個 “隱式的” 擴展:
Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
return $value == 'foo';
});
注意: 隱式的擴展僅僅是暗示屬性是必須的,不論它實際上是缺失的值或者是空的屬性,這都取決于你。