Validation 类別
类別幫助你驗證使用者輸入,如果你想要同時建立一个表单&它的驗證,
使用 Fieldset 类別代替。
配置
Validation 类別可以選擇性的透過全域应用程序配置档案 app/config/config.php 來配置。定義一个名为 'validation' 的段落,在其中以下設定可以被定義:
變数 |
类型 |
預設 |
描述 |
no_errors |
字串 |
''
|
如果沒有发现驗證错误要回傳的字串。 |
open_list |
字串 |
'<ul>'
|
要被附加到错误列表前的字串。通常这是某種形式的 HTML 來格式化列表。預設情況下,它被格式化为一个無序列表。 |
close_list |
字串 |
'</ul>'
|
要被附加到错误列表後的字串。 |
open_error |
字串 |
'<li>'
|
要被附加到每个单一错误訊息前的字串。 |
close_error |
字串 |
'</li>'
|
要被附加到每个单一错误訊息後的字串。 |
quote_label |
布林 |
false
|
如果为 true,而且驗證欄位的标籤包含空白,該标籤会被括在雙引號中,以增強可讀性。 |
global_input_fallback |
布林 |
true
|
如果为 true,而且值在輸入陣列找不到,該值将退回到 Input::param。 |
如果全域配置中缺少这些值中的一个或多个時,类別将使用定義在这張表中的預設值。
用法
要開始驗證你需要建立一个物件,这可以是名为 "default" 的預設物件,
或者你可以命名它如果你需要多个驗證物件。
// 使用預設
$val = Validation::forge();
// ……或給它命名
$val = Validation::forge('my_validation');
在让它實例化之後,你可以開始添加欄位給它。这與使用 Fieldset 类別的運作完全一樣,
然而这裡我們只記錄首選的用法。
$val = Validation::forge('my_validation');
// 添加一个 username 欄位,給它 "Your username" 标籤并让它为必要
$val->add('username', 'Your username')->add_rule('required');
// 现在添加另一个 password 欄位,并让它必須包含至少 3 个最多 10 个字元
$val->add('password', 'Your password')->add_rule('required')
->add_rule('min_length', 3)
->add_rule('max_length', 10);
// 现在为 gender 添加另一个欄位,并要求它包含 "M" 或 "F" 其中之一。
$val->add('gender', 'Your gender')->add_rule('required')
->add_rule('match_collection', array('M', 'F'));
add_rule() 方法的第一參数除了提供的驗證方法之外,可以包含 PHP 原生函式名稱、任何有效的 PHP
回呼(callback)和閉包(Closure)。該方法会取得要被驗證做为其第一參数的值,
以及任何更多可以給 add_rule() 方法的參数值。
我們也提供了更短的語法,相對这非常受限。它不会接受陣列回呼(array-callback)、
閉包(closure)或字串以外的參数。你也不能在你的形式中使用管道符號(|)當你使用 'match_pattern'規則,
因为該符號被用來拆分定義的規則。
// 與上面範例相同的欄位
$val = Validation::forge('my_validation');
$val->add_field('username', 'Your username', 'required');
$val->add_field('password', 'Your password', 'required|min_length[3]|max_length[10]');
$val->add_field('gender', 'Your gender', 'required|match_collection[M,F]');
一旦所有欄位都被添加,你可以执行你的驗證。这将預設为 $_POST 輸入,
但可以在給一个輸入陣列時被擴充并覆寫。
// 执行剛发布的驗證
if ($val->run())
{
// 在驗證成功時处理你的東西
}
else
{
// 驗證失敗
}
// 替代上面,覆寫 POST 中的 username,password 仍在 POST 中被徵詢
if ($val->run(array('username' => 'something')))
在驗證执行後,有三个關於輸入資訊的可用方法:
// 取得一个驗證成功欄位 => 值配對的陣列
$vars = $val->validated();
// 取得一个驗證错误为欄位 => 错误配對的陣列
$errors = $val->error();
// 取得一个已驗證輸入的陣列,这合併了 post 和給 run() 的輸入
$input = $val->input();
// 这些方法也都可以只取得单一欄位的值
$var = $val->validated('username');
驗證也可以部份执行,在这種情況下甚至 required 欄位会被忽略,當他們不在 POST 中或輸入給 run()。
透過設定执行的第二參数为 true 能做到。
// 这会只驗證 password,當 username 沒有出现在 POST 時
$val->run(array('password' => 'whatever'), true);
驗證規則
請注意,所有方法(甚至 min_length)在空白輸入時也会回傳 true。
也要要求欄位你應該添加 "required" 規則。
这些規則都可以像以下这樣被使用:
// 一般使用範例,一个沒參数的規則,和另一个有參数的規則
$val->add('email', 'Email address')->add_rule('match_value', 'me@mydomain.com', true)->add_rule('valid_email');
$val->add_field('email', 'Email address', 'match_value[me@mydomain.com,1]|valid_email');
規則表
required |
(無) |
該欄位必須被設定并給一些不是 null、
false 或空字串的值。
|
required_with |
$fieldname |
如果所給的 $fieldname 欄位被設定,該欄位必須被設定。
|
match_value |
$compare, $strict = false |
該欄位輸入必須符合 $compare,会使用 == 做,除非第二參数也給 true
(那麼会使用 ===)。
|
match_pattern |
$pattern |
会嘗试針對所給 $pattern(必須是完整 PREG 正規表達式)相配值。
注意:你 不能 在你的形式中使用管道符號(|)當你使用短語法,因为該符號被用來在字串中拆分規則。
|
match_field |
$field |
会嘗试相配該欄位與所給名稱的欄位,
相配会使用 ===。
重要:你只能針對此規則添加到欄位之前的欄位進行相配。
|
match_collection |
$collection = array() |
会试著針對集合的有效值進行欄位匹配。
|
min_length |
$length |
测试該字串是否包含至少 $length 的字元数。
|
max_length |
$length |
测试該字串是否包含不超過 $length 的字元数。
|
exact_length |
$length |
测试該字串是否有准確 $length 的字元数。
|
valid_date |
$format, $strict = true |
驗證所給輸入是否为有效的日期格式。如果有給 $format 參数,驗證会使用指定格式。
会嚴格(例如:閏年)檢查除非第二參数是給 false。
|
valid_email |
(無) |
驗證所給輸入是否为有效的 Email 地址。
|
valid_emails |
$separator(選擇性) |
驗證多个以逗號(或 $separator)分隔的 Email 地址。
|
valid_url |
(無) |
驗證所給輸入是否是有效的 URL。
|
valid_ip |
(無) |
驗證所給輸入是否是有效的 IP。
|
numeric_min |
$min_val |
测试所給輸入是否是一个大於 $min_val 的数字,
它不檢查或轉化輸入为数字值,所以任何非数字值会被認为是 0。
使用 PHP 函式 is_numeric 先行檢查。
|
numeric_max |
$max_val |
测试所給輸入是否是一个小於 $max_val的数字。
(關於非数字值詳見 numeric_min 規則)
|
numeric_between |
$min_val, $max_val |
测试所給輸入是否是一个在 $min_val 和 $max_val 之間的数字。
(關於非数字值詳見 numeric_min 規則)
重要:指定的號码包含在範圍中。
|
valid_string |
$flags = array('alpha', 'utf8') |
見以下。
|
有效字串規則
驗證字串是否堅持 $flags 參数設定的條件。
接受的标誌有:
alpha |
允許字母字元。 |
uppercase |
與只允許大寫字元字母的組合使用。 |
lowercase |
與只允許小寫字元字母的組合使用。 |
numeric |
允許数字字元。 |
spaces |
允許一般空白。 |
newlines |
允許換行符號。 |
tabs |
允許 tab。 |
dots |
允許點。 |
commas |
允許逗號。 |
punctuation |
允許點、逗號、驚嘆號、問號、冒號和分號。 |
dashes |
允許破折號和底線。 |
singlequotes |
允許单引號。 |
doublequotes |
允許雙引號。 |
quotes |
允許单引號和雙引號。 |
forwardslashes |
允許正斜線。 |
backwardslashes |
允許反斜線。 |
slashes |
所有正反斜線。 |
brackets |
允許開啟和關閉的括號。 |
braces |
允許開啟和關閉的大括號。 |
utf8 |
添加 UTF8 修飾符到正規表達式。 |
擴充 Validation 类別
擴充 Validation 类別有幾種辦法:
1. 擴充核心类別像擴充核心类別中的敘述
2. 在 app/classes/myrules.php 中建立一个类別(例如)
// app/classes/myrules.php
class MyRules
{
// 注意这是一个靜態方法
public static function _validation_unique($val, $options)
{
list($table, $field) = explode('.', $options);
$result = DB::select(DB::expr("LOWER (\"$field\")"))
->where($field, '=', Str::lower($val))
->from($table)->execute();
return ! ($result->count() > 0);
}
// 注意这是一个非靜態方法
public function _validation_is_upper($val)
{
return $val === strtoupper($val);
}
}
// 并且像这樣呼叫它:
$val = Validation::forge();
// 注意靜態與非靜態驗證規則之間的差異:
// 靜態地添加,将只能使用靜態方法
$val->add_callable('MyRules');
// 非靜態地添加,将可以使用靜態與非靜態方法
$val->add_callable(new MyRules());
$val->add('username', 'Your username', array(), array('trim', 'strip_tags', 'required', 'is_upper'))
->add_rule('unique', 'users.username');
3. 從模型呼叫回呼(callback),它運作就像上面所描述的方法,但我們只需要用其他方式呼叫它:
$val = Validation::forge();
$val->add_model('Model_User');
注意:
你需要用於方法的 '_validation_' 前綴以在驗證中是可用的。
注意:
如果你傳遞类別名稱做为一个字串,驗證方法必須被定義为靜態。如果方法不是靜態,你将必須傳遞一个物件實例做为 callable()。
使用 Validation::active() 和 Validation::active_field() 來分別取得目前活躍的 validation 實例與目前被驗證的欄位会是有用的。
例如,在上述你可以这樣做:
public static function _validation_unique($val, $options)
{
Validation::active()->set_message('unique', 'The field :label must be unique, but :value has already been used');
...
}