驗證
基本用法
Laravel 透過 Validation
類別讓你可以簡單、方便的驗證資料正確性及查看驗證的錯誤訊息。
基本驗證範例
$validator = Validator::make(
array('name' => 'Dayle'),
array('name' => 'required|min:5')
);
我們透過 make
這個方法來的第一個參數設定該被驗證資料名稱,然後第二個參數我們定義該資料可被接受的規則。
使用陣列來定義規則
多個規則可以使用「|」符號分隔,或是單一陣列作為單獨的元素分隔。
$validator = Validator::make(
array('name' => 'Dayle'),
array('name' => array('required', 'min:5'))
);
驗證多個欄位
$validator = Validator::make(
array(
'name' => 'Dayle',
'password' => 'lamepassword',
'email' => 'email@example.com'
),
array(
'name' => 'required',
'password' => 'required|min:8',
'email' => 'required|email|unique:users'
)
);
當一個 Validator
實例被建立,fails
(或 passes
)這二個方法就可以在驗證時使用,如下:
if ($validator->fails())
{
// The given data did not pass validation
}
假如驗證失敗,您可以從驗證器中接收錯誤資訊。
$messages = $validator->messages();
您可能不需要錯誤訊息,只想取得無法通過驗證的規則,您可以使用「failed」方法:
$failed = $validator->failed();
驗證檔案
Validator
類別提供了一些規則用來驗證檔案,例如 size
、mimes
等等。當需要驗證檔案時,你僅需將它們和你其他的資料一同送給驗證器即可。
使用錯誤訊息
當你呼叫一個 Validator
實例的 messages
方法後,你會得到一個 MessageBag
的變數,裡面有許多方便的方法讓你取得錯誤訊息。
查看一個欄位的第一個錯誤訊息
echo $messages->first('email');
查看一個欄位的所有錯誤訊息
foreach ($messages->get('email') as $message)
{
//
}
查看所有欄位的所有錯誤訊息
foreach ($messages->all() as $message)
{
//
}
判斷一個欄位是否有錯誤訊息
if ($messages->has('email'))
{
//
}
錯誤訊息格式化輸出
echo $messages->first('email', '<p>:message</p>');
注意: 預設錯誤訊息以 Bootstrap 相容語法輸出。
查看所有錯誤訊息並以格式化輸出
foreach ($messages->all('<li>:message</li>') as $message)
{
//
}
錯誤訊息 & 視圖
當你開始進行驗證,你將會需要一個簡易的方法去取得錯誤訊息並回傳到你的視圖中,在 Laravel 你可以很方便的處理這些事,你可以透過下面的路由例子來了解:
Route::get('register', function()
{
return View::make('user.register');
});
Route::post('register', function()
{
$rules = array(...);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
return Redirect::to('register')->withErrors($validator);
}
});
記得當驗證失敗後,我們會使用 withErrors
方法來將 Validator
實例進行重新導向。這方法會將錯誤訊息存入 session 中,這樣才能在下個請求中被使用。
然而,我們並不需要特別去將錯誤訊息綁定在我們 GET 路由的視圖中。因為 Laravel 會確認在 Session 資料中是否有錯誤訊息,並且自動將它們綁定至視圖中。所以請注意,$errors
變數存在於所有的視圖中,所有的請求裡,讓你可以直接假設 $errors
變數已被定義且可以安全地使用。$errors
變數是 MessageBag
類別的一個實例。
所以,重新導向之後,你可以自然的在視圖中使用 $errors
變數:
<?php echo $errors->first('email'); ?>
命名錯誤清單
假如你在一個頁面中有許多的表單,你可能希望為錯誤命名一個 MessageBag
。這將讓你針對特定的表單查看其錯誤訊息,我們只要簡單的在 withErrors
的第二個參數設定名稱即可:
return Redirect::to('register')->withErrors($validator, 'login');
接著你可以從一個 $errors
變數中取得已命名的 MessageBag
實例:
<?php echo $errors->login->first('email'); ?>
既存的驗證規則
以下是既存的驗證規則清單與他們的函式名稱:
- Accepted
- Active URL
- After (Date)
- Alpha
- Alpha Dash
- Alpha Numeric
- Array
- Before (Date)
- Between
- Boolean
- Confirmed
- Date
- Date Format
- Different
- Digits
- Digits Between
- Exists (Database)
- Image (File)
- In
- Integer
- IP Address
- Max
- MIME Types
- Min
- Not In
- Numeric
- Regular Expression
- Required
- Required If
- Required With
- Required With All
- Required Without
- Required Without All
- Same
- Size
- Timezone
- Unique (Database)
- URL
accepted
欄位值為 yes、on 或是 1 時,驗證才會通過。這在確認「服務條款」是否同意時很有用。
active_url
欄位值透過 PHP 函式 checkdnsrr
來驗證是否為一個有效的網址。
after:date
驗證欄位是否是在指定日期之後。這個日期將會使用 PHP strtotime
函式驗證。
alpha
欄位僅全數為字母字元時通過驗證。
alpha_dash
欄位值僅允許字母、數字、破折號(-)以及底線(_)
alpha_num
欄位值僅允許字母、數字
array
欄位值僅允許為陣列
before:date
驗證欄位是否是在指定日期之前。這個日期將會使用 PHP strtotime
函式驗證。
between:min,max
欄位值需介於指定的 min 和 max 值之間。字串、數值或是檔案都是用同樣的方式來進行驗證。
confirmed
欄位值需與對應的欄位值 foo_confirmation
相同。例如,如果驗證的欄位是 password
,那對應的欄位 password_confirmation
就必須存在且與 password
欄位相符。
date
欄位值透過 PHP strtotime
函式驗證是否為一個合法的日期。
date_format:format
欄位值透過 PHP date_parse_from_format
函式驗證符合 format 制定格式的日期是否為合法日期。
different:field
欄位值需與指定的欄位 field 值不同。
digits:value
欄位值需為數字且長度需為 value。
digits_between:min,max
欄位值需為數字,且長度需介於 min 與 max 之間。
boolean
欄位必須可以轉換成布林值,可接受的值為 true
、false
、1
、0
、"1"
、"0"
。
欄位值需符合 email 格式。
exists:table,column
欄位值需與存在於資料庫 table 中的 column 欄位值其一相同。
Exists 規則的基本使用方法
'state' => 'exists:states'
指定一個自訂的欄位名稱
'state' => 'exists:states,abbreviation'
你可以指定更多條件且那些條件將會被新增至「where」查詢裡:
'email' => 'exists:staff,email,account_id,1'
/* 這個驗證規則為 email 需存在於 staff 這個資料表中 email 欄位中且 account_id=1 */
透過 NULL
搭配「where」的縮寫寫法去檢查資料庫的是否為 NULL
'email' => 'exists:staff,email,deleted_at,NULL'
image
檔案必需為圖片(jpeg、png、bmp 或 gif)
in:foo,bar,...
欄位值需符合事先給予的清單的其中一個值
integer
欄位值需為一個整數值
ip
欄位值需符合 IP 位址格式。
max:value
欄位值需小於等於 value。字串、數字和檔案則是判斷 size
大小。
mimes:foo,bar,...
檔案的 MIME 類別需在給定清單中的列表中才能通過驗證。
MIME規則基本用法
'photo' => 'mimes:jpeg,bmp,png'
min:value
欄位值需大於等於 value。字串、數字和檔案則是判斷 size
大小。
not_in:foo,bar,...
欄位值不得為給定清單中其一。
numeric
欄位值需為數字。
regex:pattern
欄位值需符合給定的正規表示式。
注意: 當使用 regex
模式時,你必須使用陣列來取代「|」作為分隔,尤其是當正規表示式中含有「|」字元。
required
欄位值為必填。
required_if:field,value
欄位值在 field 欄位值為 value 時為必填。
required_with:foo,bar,...
欄位值 僅在 任一指定欄位有值情況下為必填。
required_with_all:foo,bar,...
欄位值 僅在 所有指定欄位皆有值情況下為必填。
required_without:foo,bar,...
欄位值 僅在 任一指定欄位沒有值情況下為必填。
required_without_all:foo,bar,...
欄位值 僅在 所有指定欄位皆沒有值情況下為必填。
same:field
欄位值需與指定欄位 field 等值。
size:value
欄位值的尺寸需符合給定 value 值。對於字串來說,value 為需符合的字元長度。對於數字來說,value 為需符合的整數值。對於檔案來說,value 為需符合的檔案大小(單位 kb)。
timezone
欄位值透過 PHP timezone_identifiers_list
函式來驗證是否為有效的時區。
unique:table,column,except,idColumn
欄位值在給定的資料庫中需為唯一值。如果 column(欄位)
選項沒有指定,將會使用欄位名稱。
唯一(Unique)規則的基本用法
'email' => 'unique:users'
指定一個自訂的欄位名稱
'email' => 'unique:users,email_address'
強制唯一規則忽略指定的 ID
'email' => 'unique:users,email_address,10'
增加額外的 Where 條件
你也可以指定更多的條件式到「where」查詢語句中:
'email' => 'unique:users,email_address,NULL,id,account_id,1'
上述規則為只有 account_id
為 1
的資料列會做唯一規則的驗證。
url
欄位值需符合 URL 的格式。
注意: 此函式會使用 PHP
filter_var
方法驗證。
有條件新增規則
某些情況下,你可能 只想 當欄位有值時,才進行驗證。只要增加 sometimes
條件進條件列表中,就可以快速達成:
$v = Validator::make($data, array(
'email' => 'sometimes|required|email',
));
在上述範例中,email
欄位只會在當其在 $data
陣列中有值的情況下才會被驗證。
複雜的條件式驗證
有時,你可以希望給定欄位在其他欄位有超過 100 時為必填。或者你希望兩個欄位,當其一欄位有值時,另一欄位將會有一個給定的值。增加這樣的驗證條件並不痛苦。首先,利用你尚未更動的 靜態規則 創建一個 Validator
實例:
$v = Validator::make($data, array(
'email' => 'required|email',
'games' => 'required|numeric',
));
假設我們的網頁應用程式是專為遊戲收藏家所設計。如果遊戲收藏家收藏超過一百款遊戲,我們希望他們說明為什麼他們擁有這麼多遊戲。像是,可能他們經營一家二手遊戲商店,或是他們可能只是享受收集的樂趣。有條件的加入此需求,我們可以在 Validator
實例中使用 sometimes
方法。
$v->sometimes('reason', 'required|max:500', function($input)
{
return $input->games >= 100;
});
傳遞至 sometimes
方法的第一個參數是我們要條件式認證的欄位名稱。第二個參數是我們想加入驗證規則。閉包(Closure)
作為第三個參數傳入,如果回傳值為 true
那該規則就會被加入。這個方法可以輕而易舉的建立複雜的條件式驗證。你也可以一次對多個欄位增加條件式驗證:
$v->sometimes(array('reason', 'cost'), 'required', function($input)
{
return $input->games >= 100;
});
注意: 傳遞至你的
Closure
的$input
參數為Illuminate\Support\Fluent
的實例且用來作為存取你的輸入及檔案的物件。
自訂錯誤訊息
如果需要,你可以為驗證自訂錯誤訊息取代預設錯誤訊息。這裏有幾個方式可以設定客制訊息。
傳遞客制訊息進驗證器
$messages = array(
'required' => 'The :attribute field is required.',
);
$validator = Validator::make($input, $rules, $messages);
注意: 在驗證中,
:attribute
佔位符會被欄位的實際名稱給取代。你也可以在驗證訊息中使用其他的佔位符。
其他的驗證佔位符
$messages = array(
'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',
);
為特定屬性給予一個客制化訊息
有時你只想為一個特定欄位指定一個客制錯誤訊息:
$messages = array(
'email.required' => 'We need to know your e-mail address!',
);
在語言檔中指定客制訊息
某些狀況下,你可能希望在語言檔中設定你的客制訊息,而非直接將他們傳遞給 Validator
。要達到目的,將你的訊息增加至 app/lang/xx/validation.php
檔案的 custom
陣列中。
'custom' => array(
'email' => array(
'required' => 'We need to know your e-mail address!',
),
),
自訂驗證規則
註冊自訂驗證規則
Laravel 提供了各種有用的驗證規則,但是,你可能希望可以設定一些自己專用的。註冊自訂的驗證規則的方法之一就是使用 Validator::extend
方法:
Validator::extend('foo', function($attribute, $value, $parameters)
{
return $value == 'foo';
});
客制驗證器閉包接收三個參數:要被驗證的 $attribute(屬性)
的名稱,屬性的值 $value
,傳遞至驗證規則的 $parameters
陣列。
你同樣可以傳遞一個類別和方法到 extend
方法中,取代原本的閉包:
Validator::extend('foo', 'FooValidator@validate');
注意,你同時需要為你的自訂規則訂立一個錯誤訊息。你可以使用行內自訂訊息陣列或是在認證語言檔裡新增。
擴展 Validator 類別
除了使用閉包回呼(Closure callbacks)來擴展 Validator 外,你一樣可以直接擴展 Validator 類別。你可以寫一個擴展自 Illuminate\Validation\Validator
的驗證器類別。你也可以增加驗證方法到以 validate
為開頭的類別中:
<?php
class CustomValidator extends Illuminate\Validation\Validator {
public function validateFoo($attribute, $value, $parameters)
{
return $value == 'foo';
}
}
Registering A Custom Validator Resolver
接下來,你需要註冊你自訂驗證器擴展:
Validator::resolver(function($translator, $data, $rules, $messages)
{
return new CustomValidator($translator, $data, $rules, $messages);
});
當創建自訂驗證規則時,你可能有時需要為錯誤訊息定義客制化的佔位符。你可以如上所述創建一個自訂的驗證器,然後增加 replaceXXX
函式進驗證器中。
protected function replaceFoo($message, $attribute, $rule, $parameters)
{
return str_replace(':foo', $parameters[0], $message);
}
如果你想要增加一個自訂訊息「replacer」但不擴展 Validator
類別,你可以使用 Validator::replacer
方法:
Validator::replacer('rule', function($message, $attribute, $rule, $parameters)
{
//
});