數據校驗 對於任何應用程序,數據校驗都是重要部分,因為它有且於確保模型中的數據遵守了應用程序的業務規則。 例如,你可能想要確保密碼最少要有8位,或者確保用戶名唯一。 定義校驗規則使表單處理非常非常簡單。 校驗過程有許多不同的面。本節覆蓋的是其中模型這一面。 即:在調用模型中的 save() 方法時發生了什麼。 關於如何處理校驗錯誤的顯示的更多信息,參見: 表單助手。 數據校驗的第一步是在模型中建立校驗規則。這是用模型定義中的 Model::validate 數組實現的: 1 class User extends AppModel { 2 public $validate = array(); 3 } 在上面的示例中,$validate 數組被添加到 User 模型中,但數組不包含校驗規則。 假設 users 表有 login、password、email 和 born 列,下面的示例展示了應用在這些列上的一些簡單的校驗規則: 1 class User extends AppModel { 2 public $validate = array( 3 'login' => 'alphaNumeric', 4 'email' => 'email', 5 'born' => 'date' 6 ); 7 } 上例展示了如何向模型列添加校驗規則。對於 login 列,只接受字母和數字,email 必須是有效的郵件地址,born 必須是有效的日期。 如果提交的數據違反了定義的規則,這些校驗規則定義能使 CakePHP 自動在表單中顯示錯誤信息。 CakePHP 有許多校驗規則,且易於使用。 一些內置的規則允許你校驗 email、URL 和 信用卡數字的格式 - 我們稍後會講到它們的細節。 下面是一個非常復雜的校驗的示例,利用了一些內置的校驗規則: 1 class User extends AppModel { 2 public $validate = array( 3 'login' => array( 4 'alphaNumeric' => array( 5 'rule' => 'alphaNumeric', 6 'required' => true, 7 'message' => 'Alphabets and numbers only' 8 ), 9 'between' => array( 10 'rule' => array('between', 5, 15), 11 'message' => 'Between 5 to 15 characters' 12 ) 13 ), 14 'password' => array( 15 'rule' => array('minLength', '8'), 16 'message' => 'Minimum 8 characters long' 17 ), 18 'email' => 'email', 19 'born' => array( 20 'rule' => 'date', 21 'message' => 'Enter a valid date', 22 'allowEmpty' => true 23 ) 24 ); 25 } 其中兩條是為 login 定義的:它只能包含字母和數字,並且長度必須在5至15之間。 password 列必須不少於8位長。 email 必須是有效的郵件地址,並且 born 必須是有效的日期。 還要注意的是,怎樣定義校驗失敗時顯示特定的錯誤信息。 上面的例子中,單個列可以使用多個校驗規則。如果內置的規則不能滿足你的要求,你可以添加自己需要的校驗規則。 現在你已經看到了數據校驗的全景,讓我們瞧瞧如何在模型中定義這些規則。有三種不同的方法:簡單數組、每個列的單個規則、每個列的多個規則。 簡單規則 顧名思義,這是定義校驗規則最簡單的方法。 這種方法定義規則是標准語法是: 1 public $validate = array('fieldName' => 'ruleName'); ‘fieldName’ 是規則所適用的列的名字,‘ruleName’是預定義的規則名,例如 ‘alphaNumeric’、’email’ 或者 ‘isUnique’。 例如,要確保用戶所提供的是格式正確的郵件地址,可以使用如下規則: 1 public $validate = array('user_email' => 'email'); 每個列一個規則 這種定義手法對校驗規則的工作有更好的控制。在我們討論這個之前,先來看看向單個列添加一條規則的標准用法: 1 public $validate = array( 2 'fieldName1' => array( 3 'rule' => 'ruleName', // or: array('ruleName', 'param1', 'param2' ...) 4 'required' => true, 5 'allowEmpty' => false, 6 'on' => 'create', // or: 'update' 7 'message' => 'Your Error Message' 8 ) 9 ); ‘rule’ 鍵是必須的。如果僅設置了 ‘required’ => true,表單驗證將無法正確工作。因為 ‘required’ 不是實際的規則。 正如你看到的,每個列(上面只演示了一個列)與包含了如下五個鍵的數組關聯:‘rule’、 ‘required’、 ‘allowEmpty’、 ‘on’ 和 ‘message’。讓我們仔細地觀察這幾個鍵。 rule ‘rule’ 方法定義了校驗方面並且指定了一個值或者一個數組。這個特定的 ‘rule’ 可能是模型中的一個方法的名字,核心 Validation 類的一個方法的名字,或者正則表達式。要了解關於默認規則的更多信息,請參見 內核核驗規則。 如果 rule 不包含任何參數,’rule’ 可以是單個值,例如: 1 public $validate = array( 2 'login' => array( 3 'rule' => 'alphaNumeric' 4 ) 5 ); 如果 rule 包含參數(例如 max,min 或者范圍),’rule’ 將是一個數組: 1 public $validate = array( 2 'password' => array( 3 'rule' => array('minLength', 8) 4 ) 5 ); 記住,用數組方式定義規則時,’rule’ 鍵是必須的。 required 這個鍵接受一個邏輯值、create 或者 update。將其設置為 true 將使這一列總是被必須的。設置為 create 或者update 將使這一列只在更新或創建操作時必須。如果 ‘required’ 等於 true,數組中必須提供此列。例如,如果定義如下校驗規則: 1 public $validate = array( 2 'login' => array( 3 'rule' => 'alphaNumeric', 4 'required' => true 5 ) 6 ); 傳遞給模型的 save() 方法的數據必須包含提供給 login 列的數據。如果它不存在,那麼校驗失敗。這個鍵的默認值為邏輯 false。 required => true 與 校驗規則中的 notEmpty() 不是一回事兒。required => true 表示這個數組 鍵 必須提供 - 不意味著它必須有值。如果數據集沒有提供,校驗失敗,但是如果提交了空值(’‘)是有可能成功的(這依賴於規則的詳細定義)。 在 2.1 版更改: 添加了對 create 和 update 的支持。 allowEmpty 如果設置為 false,這個列的值必須是 非空的,, the field value must be nonempty, 其中 “nonempty” 非空的定義為 !empty($value) || is_numeric($value)。 對於數值檢測,當 $value 為0時,CakePHP 認為是正確的。 required 與 allowEmpty 的不同可能會造成混亂。'required' => true 意味著 $this->data 中不提供帶有這個列的鍵 就不能保存模型; 而 'allowEmpty' => false 則像上面描述的尋,是確保這個列的 值 必須是非空的。 on ‘on’ 鍵可以被設置為 ‘update’ 或 ‘create’。它提供了允許一些規則應用於創建新記錄的過程中或者更新記錄的過程中的機制。 如果一條規則被定義成 ‘on’ => ‘create’,這條規則僅在創建新記錄的過程中有效。類似的,如果它被定義成 ‘on’ => ‘update’,將只在更新記錄的過程中有效。 ‘on’ 的默認值為空(null)。當 ‘on’ 為空(null),這條規則在創建和更新過程中同時生效。 message message 鍵為規則自定義校驗錯誤時的顯示信息: 1 public $validate = array( 2 'password' => array( 3 'rule' => array('minLength', 8), 4 'message' => 'Password must be at least 8 characters long' 5 ) 6 ); 每個列多條規則 上面的技術為我們提供了比簡單的規則分配更大的靈活性,再進一步,我們能獲得更詳細的數據校驗控制。下面我們介紹一種允許我們為每個列賦予多個規則的技術。 想要為單個列賦多個校驗規則,基本的寫法如下: 1 public $validate = array( 2 'fieldName' => array( 3 'ruleName' => array( 4 'rule' => 'ruleName', 5 // 類似 on,required 等擴展鍵放在這裡... 6 ), 7 'ruleName2' => array( 8 'rule' => 'ruleName2', 9 // 類似 on,required 等擴展鍵放在這裡... 10 ) 11 ) 12 ); 正像你看到的那樣,這和上一節中所做的非常相似。在那兒,每個列僅有一個校驗參數數組。在這兒,每個 ‘fieldName’ 是一個規則數組的索引。每個 ‘ruleName’ 包含一個校驗參數數組。 下面是一個帶有實際例子的更好诠釋: 1 public $validate = array( 2 'login' => array( 3 'loginRule-1' => array( 4 'rule' => 'alphaNumeric', 5 'message' => 'Only alphabets and numbers allowed', 6 ), 7 'loginRule-2' => array( 8 'rule' => array('minLength', 8), 9 'message' => 'Minimum length of 8 characters' 10 ) 11 ) 12 ); 上例為 login 列定義了兩個規則: loginRule-1 和 loginRule-2。如你所見,每個規則的標識隨意命名。 在為單個列定義多條規則時,’required’ 和 ‘allowEmpty’ 鍵僅需在第一個規則中使用一次。 last 對於每個列有多條規則的情況,默認的如果一個規則校驗失敗並返回錯誤消息,該列的後續規則將不再計算。如果希望一個規則失敗了校驗仍然繼續,就將這條規則的 last 鍵設置為 false。 在下面的例子中,即使 “rule1” 失敗,”rule2” 仍將計算,並且在 “rule2” 也失敗的時候返回所有的錯誤信息: 1 public $validate = array( 2 'login' => array( 3 'rule1' => array( 4 'rule' => 'alphaNumeric', 5 'message' => 'Only alphabets and numbers allowed', 6 'last' => false 7 ), 8 'rule2' => array( 9 'rule' => array('minLength', 8), 10 'message' => 'Minimum length of 8 characters' 11 ) 12 ) 13 ); 在用數組指定校驗規則時,可以不使用 message 鍵。考慮下面的例子: 1 public $validate = array( 2 'login' => array( 3 'Only alphabets and numbers allowed' => array( 4 'rule' => 'alphaNumeric', 5 ), 6 ) 7 ); 如果 alphaNumeric 規則失敗,由於沒有設置 message 鍵,這條規則的鍵 ‘Only alphabets and numbers allowed’ 將作為錯誤消息被返回。 自定義校驗規則 如果找不到所需的校驗規則,可以自定義。有兩種方法進行自定義: 自定義正則表達式,或者創建自定義校驗方法。 自定義校驗正則表達式 如果所需的校驗手段能夠通過正則表達式匹配來完成,可以自定義表達式作為列的校驗規則: 1 public $validate = array( 2 'login' => array( 3 'rule' => '/^[a-z0-9]{3,}$/i', 4 'message' => 'Only letters and integers, min 3 characters' 5 ) 6 ); 上例檢查了 login 是否僅包含字母和整數,並且不得小於3個字符。 “rule” 中的正則表達式必須用斜槓(/)括住。末尾的可選項 ‘i’ 表示正則表達式是不區分大小寫的。 添加自己的校驗方法 有時僅用正則模式校驗數據還不夠。 例如,想要確保促銷碼僅能被使用 25 次,需要添加自己的校驗方法,示例如下: 1 class User extends AppModel { 2 3 public $validate = array( 4 'promotion_code' => array( 5 'rule' => array('limitDuplicates', 25), 6 'message' => 'This code has been used too many times.' 7 ) 8 ); 9 10 public function limitDuplicates($check, $limit) { 11 // $check 的值: array('promotion_code' => 'some-value') 12 // $limit 的值: 25 13 $existing_promo_count = $this->find('count', array( 14 'conditions' => $check, 15 'recursive' => -1 16 )); 17 return $existing_promo_count < $limit; 18 } 19 } 被校驗的當前列被傳遞給函數,作為該函數的第一個參數,是以列名為鍵,以 post 來的數據為值構成的關聯數組。 如果想要給校驗函數傳遞額外的參數,向 ‘rule’ 數組添加一個元素,並在函數中以擴展參數來處理它們(排在主參數$check 之後)。 校驗函數可以放在模型中(就像上面的例子),也可以放在模型實現的行為中。包括映射方法。 模型/行為 方法最先校驗,優先於在 Validation 類的方法。這意味著可以在應用程序級別(通過在 AppModel 添加方法)或模型級別覆蓋已存在的校驗方法(例如 alphaNumeric())。 在編寫可用於多個列的校驗規則,從 $check 數組中提取列值時要小心。$check 數組是以表單域名作為鍵、表單域值作為值構成的。存儲在 $this->data 成員變量中的整個記錄被校驗。 1 class Post extends AppModel { 2 3 public $validate = array( 4 'slug' => array( 5 'rule' => 'alphaNumericDashUnderscore', 6 'message' => 'Slug can only be letters, numbers, dash and underscore' 7 ) 8 ); 9 10 public function alphaNumericDashUnderscore($check) { 11 // $data 數組是以表單域名為鍵被傳遞的 12 // 必須提取該值以使函數通用 13 $value = array_values($check); 14 $value = $value[0]; 15 16 return preg_match('|^[0-9a-zA-Z_-]*$|', $value); 17 } 18 } 注解 自定義的校驗方法的可見性必須是 public。不支持 protected 和 private 級別的校驗方法。 如果規則有效,該方法返回 true。如果校驗失敗,返回 false。另一個有效的返回值是一個字符串,它是要顯示的錯誤信息。返回字符串意味著校驗失敗。 這個字符串將覆蓋 $validate 數組中的信息集,並將作為列為什麼無效的原因顯示在視圖的表單中。 動態改變校驗規則 使用 $validate 屬性定義校驗規則是為每個模型定義靜態規則的好辦法。不過有時你需要從預定義的規則集中動態添加、改變或刪除校驗規則。 所有的校驗規則都存儲在 ModelValidator 對象中,它掌握著模型中各個列的每個規則集。 通過通知這個對象為想要的列存儲新的校驗方法來定義新的校驗規則是很簡單的。 添加新的校驗規則 2.2 新版功能. ModelValidator 對象提供了數個向集中添加新列的途徑。第一個是使用 add 方法: 1 // 在模型類中 2 $this->validator()->add('password', 'required', array( 3 'rule' => 'notEmpty', 4 'required' => 'create' 5 )); 這樣就會為模型中的 password 列添加單一規則。可以鏈式多次調用 add 來創建多條所需的規則: 1 // 在模型類中 2 $this->validator() 3 ->add('password', 'required', array( 4 'rule' => 'notEmpty', 5 'required' => 'create' 6 )) 7 ->add('password', 'size', array( 8 'rule' => array('between', 8, 20), 9 'message' => 'Password should be at least 8 chars long' 10 )); 也可以一次性為單個列添加多條規則: 1 $this->validator()->add('password', array( 2 'required' => array( 3 'rule' => 'notEmpty', 4 'required' => 'create' 5 ), 6 'size' => array( 7 'rule' => array('between', 8, 20), 8 'message' => 'Password should be at least 8 chars long' 9 ) 10 )); 或者也可以利用數組接口使用此對象,直接為列設置規則: 1 $validator = $this->validator(); 2 $validator['username'] = array( 3 'unique' => array( 4 'rule' => 'isUnique', 5 'required' => 'create' 6 ), 7 'alphanumeric' => array( 8 'rule' => 'alphanumeric' 9 ) 10 ); 編輯現有的校驗規則 2.2 新版功能. 可以使用 validator 對象編輯現有的校驗規則,有幾種方法可以修改現有規則、向列追加方法或者從列規則集中完整地刪除一條規則: 1 // 在模型類中 2 $this->validator()->getField('password')->setRule('required', array( 3 'rule' => 'required', 4 'required' => true 5 )); 也可以使用類似的方法完整地替換一個列的所有規則: 1 // 在模型類中 2 $this->validator()->getField('password')->setRules(array( 3 'required' => array(...), 4 'otherRule' => array(...) 5 )); 如果只是想領回規則中的單個屬性,可以直接設置 CakeValidationRule 對象的屬性: 1 // 在模型類中 2 $this->validator()->getField('password') 3 ->getRule('required')->message = 'This field cannot be left blank'; CakeValidationRule 中的屬性是由在模型中使用 $validate 屬性定義相應規則的有效數組鍵來命名的。 在向規則集中添加規則時,也可以使用數組接口編輯已有的規則: 1 $validator = $this->validator(); 2 $validator['username']['unique'] = array( 3 'rule' => 'isUnique', 4 'required' => 'create' 5 ); 6 7 $validator['username']['unique']->last = true; 8 $validator['username']['unique']->message = 'Name already taken'; 從規則集中刪除規則 2.2 新版功能. 完整地刪除一個列的所有規則和只刪除一個列規則集中的單個規則都是可以的: 1 // 完成地刪除一個列的所有規則 2 $this->validator()->remove('username'); 3 4 // 從 password 中刪除 'required' 規則 5 $this->validator()->remove('password', 'required'); 還可以使用數組接口從規則集中刪除規則: 1 $validator = $this->validator(); 2 // 完整地刪除一個列的所有規則 3 unset($validator['username']); 4 5 // 從 passworkd 中刪除 'required' 規則 6 unset($validator['password']['required']); 內核核驗規則 class Validation CakePHP 的 Validation 類包含許多能使模型數據校驗更容易的校驗規則。這個類包含許多常用的不需要自己編寫的校驗技術。 下面是全部規則的完整列表及其用法示例。 static Validation::alphaNumeric(mixed $check) 列數據必須只包含字母和數字。 1 public $validate = array( 2 'login' => array( 3 'rule' => 'alphaNumeric', 4 'message' => 'Usernames must only contain letters and numbers.' 5 ) 6 ); static Validation::between(string $check, integer $min, integer $max) 列的數據長度必須位於指定的數值范圍。必須同時提供最小值和最大值。Uses = not.: 1 public $validate = array( 2 'password' => array( 3 'rule' => array('between', 5, 15), 4 'message' => 'Passwords must be between 5 and 15 characters long.' 5 ) 6 ); 數據的長度是指”字符串數據的字節數”。要小心,當處理非 ASCII 字符時,其值可能大於字符數。 static Validation::blank(mixed $check) 這條規則用於確保列值為空或者其值僅包含空白字符。空白字符包括 空格、tab、回車和換行。 1 public $validate = array( 2 'id' => array( 3 'rule' => 'blank', 4 'on' => 'create' 5 ) 6 ); static Validation::boolean(string $check) 列數據必須是邏輯值。有效值包括 true 或 false,整數值 0 或 1,字符串值 ‘0’ 或 ‘1’。 1 public $validate = array( 2 'myCheckbox' => array( 3 'rule' => array('boolean'), 4 'message' => 'Incorrect value for myCheckbox' 5 ) 6 ); static Validation::cc(mixed $check, mixed $type = 'fast', boolean $deep = false, string $regex = null) 這條規則用於檢查數據是否是有效的信用卡編號。它有三個參數:‘type’、 ‘deep’ 和 ‘regex’。 ‘type’鍵能賦的值有‘fast’、 ‘all’下列值之一: amex bankcard diners disc electron enroute jcb maestro mc solo switch visa voyager 如果‘type’設為‘fast’,檢驗的是主信用卡的編碼格式。‘type’設置為‘all’校驗所有信用卡類型。也可以將 ‘type’設置為希望檢驗的類型的數組。 ‘deep’鍵需要設置為邏輯值。如果為 true,校驗規則將檢查信用卡的 Luhn 算法(http://en.wikipedia.org/wiki/Luhn_algorithm)。默認值為 false。 ‘regex’鍵允許提供自定義的用於校驗信用卡編號的正則表達式: 1 public $validate = array( 2 'ccnumber' => array( 3 'rule' => array('cc', array('visa', 'maestro'), false, null), 4 'message' => 'The credit card number you supplied was invalid.' 5 ) 6 ); static Validation::comparison(mixed $check1, string $operator = null, integer $check2 = null) Comparison 用於比較數字值。支持 “is greater”、”isless”、”greater or equal”、”less or equal”、”equal to” 和 “not equal”。以下為示例: 1 public $validate = array( 2 'age' => array( 3 'rule' => array('comparison', '>=', 18), 4 'message' => 'Must be at least 18 years old to qualify.' 5 ) 6 ); 7 8 public $validate = array( 9 'age' => array( 10 'rule' => array('comparison', 'greater or equal', 18), 11 'message' => 'Must be at least 18 years old to qualify.' 12 ) 13 ); static Validation::custom(mixed $check, string $regex = null) 用於自定義正則表達式: 1 public $validate = array( 2 'infinite' => array( 3 'rule' => array('custom', '\u221E'), 4 'message' => 'Please enter an infinite number.' 5 ) 6 ); static Validation::date(string $check, mixed $format = 'ymd', string $regex = null) 這條規則確保提交的數據是正確的日期格式。可以傳遞一個指定要校驗的日期的格式的參數(可以是數組)。此參數可以為下列之一: ‘dmy’ 例如 27-12-2006 或 27-12-06 (間隔符可以是空格、句點、破折號、斜槓) ‘mdy’ 例如 12-27-2006 or 12-27-06 (間隔符可以是空格、句點、破折號、斜槓) ‘ymd’ 例如 2006-12-27 or 06-12-27 (間隔符可以是空格、句點、破折號、斜槓) ‘dMy’ 分別 27 December 2006 or 27 Dec 2006 ‘Mdy’ 例如 December 27, 2006 or Dec 27, 2006 (逗號是可選的) ‘My’ 例如 (December 2006 or Dec 2006) ‘my’ 例如 12/2006 or 12/06 (間隔符可以是空格、句點、破折號、斜槓) 如果沒有提供這個鍵,就默認使用 ‘ymd’: 1 public $validate = array( 2 'born' => array( 3 'rule' => array('date', 'ymd'), 4 'message' => 'Enter a valid date in YY-MM-DD format.', 5 'allowEmpty' => true 6 ) 7 ); 當許多數據需要用一個特定的格式存儲時,你可能會考慮接受較寬泛的格式並轉換,而不是強制用戶提供一個指定的格式。你可以為客戶做的更多、更好! static Validation::datetime(array $check, mixed $dateFormat = 'ymd', string $regex = null) 這條規則確保數據是有效的日期時間格式。可以傳遞一個指定要校驗的日期的格式的參數(可以是數組)。此參數可以為下列之一: ‘dmy’ 例如 27-12-2006 或 27-12-06 (間隔符可以是空格、句點、破折號、斜槓) ‘mdy’ 例如 12-27-2006 or 12-27-06 (間隔符可以是空格、句點、破折號、斜槓) ‘ymd’ 例如 2006-12-27 or 06-12-27 (間隔符可以是空格、句點、破折號、斜槓) ‘dMy’ 分別 27 December 2006 or 27 Dec 2006 ‘Mdy’ 例如 December 27, 2006 or Dec 27, 2006 (逗號是可選的) ‘My’ 例如 (December 2006 or Dec 2006) ‘my’ 例如 12/2006 or 12/06 (間隔符可以是空格、句點、破折號、斜槓) 如果沒有提供這個鍵,就默認使用 ‘ymd’: 1 public $validate = array( 2 'birthday' => array( 3 'rule' => array('datetime', 'dmy'), 4 'message' => 'Please enter a valid date and time.' 5 ) 6 ); 可以通過傳遞第二個參數來指定自定義正則表達式。如果使用此參數,就以此為標准進行驗證。 與 date() 不同,datetime() 校驗日期和時間。 static Validation::decimal(integer $check, integer $places = null, string $regex = null) 這條規則確保數據是有效的數字。可以傳遞一個指定小數點後的數字位數的參數。如果沒有傳遞參數,數據必須是嚴格意義上的浮點數,如果沒有在小數點後發現數字,校驗就會失敗: 1 public $validate = array( 2 'price' => array( 3 'rule' => array('decimal', 2) 4 ) 5 ); static Validation::email(string $check, boolean $deep = false, string $regex = null) 這條規則校驗數據是否為有效的郵件地址。傳遞一個邏輯值作為其第二個參數,這條規則將試圖檢查地址中的主機是否是有效的: 1 public $validate = array('email' => array('rule' => 'email')); 2 3 public $validate = array( 4 'email' => array( 5 'rule' => array('email', true), 6 'message' => 'Please supply a valid email address.' 7 ) 8 ); static Validation::equalTo(mixed $check, mixed $compareTo) 這條規則確保數據與給定的值類型相同、數值相等。 1 public $validate = array( 2 'food' => array( 3 'rule' => array('equalTo', 'cake'), 4 'message' => 'This value must be the string cake' 5 ) 6 ); static Validation::extension(mixed $check, array $extensions = array('gif', 'jpeg', 'png', 'jpg')) 這條規則校驗文件擴展名是不是 .jpg 或者 .png。允許以數組方式傳遞多個擴展名。 1 public $validate = array( 2 'image' => array( 3 'rule' => array('extension', array('gif', 'jpeg', 'png', 'jpg')), 4 'message' => 'Please supply a valid image.' 5 ) 6 ); static Validation::fileSize($check, $operator = null, $size = null) 這條規則允許檢測文件長度。可以使用 $operator 來決定所需的比較類型。所有 comparison() 支持的操作這裡也支持。 此方法將通過讀取 tmp_name 鍵(如果 $check 是一個包含該鍵的數組)自動處理來自 $_FILES 的數組值: 1 public $validate = array( 2 'image' => array( 3 'rule' => array('filesize', '<=', '1MB'), 4 'message' => 'Image must be less than 1MB' 5 ) 6 ); 2.3 新版功能: 此方法是 2.3 版增加的。 static Validation::inList(string $check, array $list) 這條規則確保值在給定的集合中。它需要一個值數組。如果列值與給定的數組中的某個值匹配,則列被視為有效。 例如: 1 public $validate = array( 2 'function' => array( 3 'allowedChoice' => array( 4 'rule' => array('inList', array('Foo', 'Bar')), 5 'message' => 'Enter either Foo or Bar.' 6 ) 7 ) 8 ); static Validation::ip(string $check, string $type = 'both') 這條規則確保被提交的是有效的 IPv4 或 IPv6 地址。接受參數 ‘both’ (默認值)、’IPv4’ 或者 ‘IPv6’。 1 public $validate = array( 2 'clientip' => array( 3 'rule' => array('ip', 'IPv4'), // or 'IPv6' or 'both' (default) 4 'message' => 'Please supply a valid IP address.' 5 ) 6 ); static Validation::isUnique 列數據必須唯一,不能是被其它行用過的。 1 public $validate = array( 2 'login' => array( 3 'rule' => 'isUnique', 4 'message' => 'This username has already been taken.' 5 ) 6 ); static Validation::luhn(string|array $check, boolean $deep = false) Luhn 算法:各種標識碼的校驗算法。更多信息參見 http://en.wikipedia.org/wiki/Luhn_algorithm 。 static Validation::maxLength(string $check, integer $max) 這條規則確保數據在最大長度范圍內。 1 public $validate = array( 2 'login' => array( 3 'rule' => array('maxLength', 15), 4 'message' => 'Usernames must be no larger than 15 characters long.' 5 ) 6 ); 此處的長度是 “字符串數據的字節數”。要小心,當處理非 ASCII 字符時,其值可能大於字符數。 static Validation::mimeType(mixed $check, array $mimeTypes) 2.2 新版功能. 這條規則校驗有效的 mimeType 1 public $validate = array( 2 'image' => array( 3 'rule' => array('mimeType', array('image/gif')), 4 'message' => 'Invalid mime type.' 5 ), 6 ); static Validation::minLength(string $check, integer $min) 這條規則確保數據不低於最短長度。 1 public $validate = array( 2 'login' => array( 3 'rule' => array('minLength', 8), 4 'message' => 'Usernames must be at least 8 characters long.' 5 ) 6 ); 此處的長度是 “字符串數據的字節數”。要小心,當處理非 ASCII 字符時,其值可能大於字符數。 static Validation::money(string $check, string $symbolPosition = 'left') 這條規則確保值是一個有效的貨幣額。 第二個參數定義了貨幣符號的位置(左/右)。 1 public $validate = array( 2 'salary' => array( 3 'rule' => array('money', 'left'), 4 'message' => 'Please supply a valid monetary amount.' 5 ) 6 ); static Validation::multiple(mixed $check, mixed $options = array()) 這條規則用於校驗 多 select input 表單。所支持的參數有 “in”、”max” 和 “min”。 1 public $validate = array( 2 'multiple' => array( 3 'rule' => array('multiple', array( 4 'in' => array('do', 'ray', 'me', 'fa', 'so', 'la', 'ti'), 5 'min' => 1, 6 'max' => 3 7 )), 8 'message' => 'Please select one, two or three options' 9 ) 10 ); static Validation::notEmpty(mixed $check) 這條規則確保列不是空的。 1 public $validate = array( 2 'title' => array( 3 'rule' => 'notEmpty', 4 'message' => 'This field cannot be left blank' 5 ) 6 ); 不要在校驗 多選擇的 select input 時使用這條規則,因為這會引起錯誤。請使用 “multiple” 代替。 static Validation::numeric(string $check) 校驗傳遞的數據是不是有效的數字。 1 public $validate = array( 2 'cars' => array( 3 'rule' => 'numeric', 4 'message' => 'Please supply the number of cars.' 5 ) 6 ); static Validation::naturalNumber(mixed $check, boolean $allowZero = false) 2.2 新版功能. 這條規則檢查傳遞的數據是不是有效的自然數。如果 $allowZero 被設置為 true,0 也將是可以接受的值。 1 public $validate = array( 2 'wheels' => array( 3 'rule' => 'naturalNumber', 4 'message' => 'Please supply the number of wheels.' 5 ), 6 'airbags' => array( 7 'rule' => array('naturalNumber', true), 8 'message' => 'Please supply the number of airbags.' 9 ), 10 ); static Validation::phone(mixed $check, string $regex = null, string $country = 'all') 電話校驗針對的是美國電話號碼。如果想要校驗非美國電話號碼,可以提供一個正則表達式作為第二個參數,以覆蓋額外的號碼格式。 1 public $validate = array( 2 'phone' => array( 3 'rule' => array('phone', null, 'us') 4 ) 5 ); static Validation::postal(mixed $check, string $regex = null, string $country = 'us') 郵政編碼針對的是美國、加拿大、英國、意大利、德國和比利時。對於其它的郵政編碼,可以提供一個正則作為第二個參數。 1 public $validate = array( 2 'zipcode' => array( 3 'rule' => array('postal', null, 'us') 4 ) 5 ); static Validation::range(string $check, integer $lower = null, integer $upper = null) 這條規則確保傳遞的值在給定的范圍內。如果沒有提供范圍,這條規則檢測並確認傳遞的是當前平台上的合法值。 1 public $validate = array( 2 'number' => array( 3 'rule' => array('range', -1, 11), 4 'message' => 'Please enter a number between 0 and 10' 5 ) 6 ); 上例將接受大於 0 (例如 0.01)並且小於 10 (例如 9.99)的值。 注解 范圍的 上/下 限是不包含在內的。 static Validation::ssn(mixed $check, string $regex = null, string $country = null) Ssn 校驗美國、丹麥和荷蘭的社會安全號碼。對於其它的社會安全號碼,需要提供一個正則表達式。 1 public $validate = array( 2 'ssn' => array( 3 'rule' => array('ssn', null, 'us') 4 ) 5 ); static Validation::time(string $check) 時間校驗判斷傳遞的字符串是不是有效的時間。格式有兩種 24 小時制(HH:MM)或者 上/下午制([H]H:MM[a|p]m)。不允許有秒,也不校驗秒。 static Validation::uploadError(mixed $check) 2.2 新版功能. 這條規則檢測文件上傳是否發生了錯誤。 1 public $validate = array( 2 'image' => array( 3 'rule' => 'uploadError', 4 'message' => 'Something went wrong with the upload.' 5 ), 6 ); static Validation::url(string $check, boolean $strict = false) 這條規則檢測 URL 格式是否有效。支持 http(s)、ftp(s)、file、news 和 gopher 協議: 1 public $validate = array( 2 'website' => array( 3 'rule' => 'url' 4 ) 5 ); 要確保協議是 url,可以啟用嚴格模式,示例如下: 1 public $validate = array( 2 'website' => array( 3 'rule' => array('url', true) 4 ) 5 ); static Validation::userDefined(mixed $check, object $object, string $method, array $args = null) 運行一個用戶定義的校驗。 static Validation::uuid(string $check) 檢測值是否是有效的 uuid: http://tools.ietf.org/html/rfc4122 本地化校驗 phone() 和 postal() 校驗規則將所有它們不知道如何處理的國家前綴傳遞給帶有正確名稱的其它類。 例如,如果你住在荷蘭,可以創建如下類: 1 class NlValidation { 2 public static function phone($check) { 3 // ... 4 } 5 public static function postal($check) { 6 // ... 7 } 8 } 這個文件可以放在 APP/Validation/ 或 App/PluginName/Validation/,但是在嘗試使用它之前必須先用 App::uses() 導入。 可以用如下方式在校驗類中使用 NLValidation 類: 1 public $validate = array( 2 'phone_no' => array('rule' => array('phone', null, 'nl')), 3 'postal_code' => array('rule' => array('postal', null, 'nl')), 4 ); 當模型數據被校驗,Validation 會看到它不能處理的 nl 國家編碼,並嘗試委托給 NlValidation::postal(),將其返回值用作校驗 通過/失敗 的結果。 這個辦法允許你建立一個類來處理本地化子集或者本地化組。 獨立檢驗方法的用法沒有改變,其能力通過添加的其它校驗器傳遞。 小技巧 本地化插件已經包含了一些有用的規則: https://github.com/cakephp/localized 你也可以隨意貢獻你的本地化檢驗規則。 在控制器中校驗數據 雖然正常情況下,你只使用模型的 save 方法,偶爾你也希望只校驗數據而不保存它。 例如,你可能希望在把數據真實地保存到數據庫前,向用戶顯示一些附加信息。 此時的數據校驗與保存數據時的校驗稍有不同。 首先,將數據賦給模型: 1 $this->ModelName->set($this->request->data); 然後,使用模型的校驗方法檢測數據是否有效,如果有效返回 true,否則返回 false: 1 if ($this->ModelName->validates()) { 2 // 數據有效的邏輯 3 } else { 4 // 數據無效的邏輯 5 $errors = $this->ModelName->validationErrors; 6 } 只使用模型中指定的校驗集的子集校驗模型是可取的。 例如,有一個帶有 first_name、last_name、email 和 password 的 User 模型。 想要在建立或編輯用戶時校驗全部四個列規則。 而在用戶登錄時只校驗 email 和 passowrd 規則。 可以通過傳遞選項數據指定要校驗的列來實現: 1 if ($this->User->validates(array('fieldList' => array('email', 'password')))) { 2 // 有效 3 } else { 4 // 無效 5 } 校驗方法調用 invalidFields 方法填充模型的 validationErrors 屬性。 invalidFields 方法同時返回這些數據: 1 $errors = $this->ModelName->invalidFields(); // 包含 validationErrors 數組 校驗錯誤列表在連續調用 invalidFields() 的過程中不會進行清理。 所以如果校驗在循環內進行,又想分隔錯誤集,就不要使用 invalidFields()。取而代之的是使用 validates() 方法並訪問模型的 validationErrors 屬性。 需要重點注意的是在數據校驗前必須將其賦給模型。 這和在保存方法中不同,保存方法允許數據作為參數傳遞。 另外,謹記不必在調用 save 之前調用校驗,因為 save 將在地、實際保存前自動校驗數據。 要校驗多個模型,使用下列方法: 1 if ($this->ModelName->saveAll($this->request->data, array('validate' => 'only'))) { 2 // 無效 www.2cto.com 3 } else { 4 // 有效 5 } 如果在保存前已經校驗了數據,可以關閉校驗以防止重復檢測: 1 if ($this->ModelName->saveAll($this->request->data, array('validate' => false))) { 2 // 保存時不再校驗 3 }