yii2之數據驗證

1、場景php

         什麼狀況下須要使用場景呢?當一個模型須要在不一樣情境中使用時,若不一樣情境下須要的數據表字段和數據驗證規則有所不一樣,則須要定義多個場景來區分不一樣使用情境。例如,用戶註冊的時候須要填寫email,登陸的時候則不須要,這時就須要定義兩個不一樣場景加以區分。ios

         默認狀況下模型的場景是由rules()方法申明的驗證規則中使用到的場景決定的,也能夠經過覆蓋scenarios()方法來更具體地定義模型的全部場景,例如:web

public function scenarios() {
        return [
            ‘signup’ => ['username', 'email', 'password', 'conpassword', 'verifyCode', 'reg_time', 'log_time'],
            ‘login’ => ['username', 'password', 'verifyCode', 'rememberMe', 'log_time']
        ];
}

其中鍵爲場景名稱,值爲該場景下使用的模型屬性(稱爲活動屬性)。ajax

         指定模型場景有如下兩種方法:正則表達式

方法一:數據庫

$model = new User();
$model->scenario = ‘signup’;

方法二:json

$model = new User(['scenario' => ‘signup’]);

         能夠經過指定驗證規則中的’on’屬性來申明一條驗證規則適用的場景:bootstrap

[‘email’, ‘required’, ‘on’ => ‘signup’]

         場景主要用於模型屬性塊賦值和數據驗證。調用模型類的load()方法進行塊賦值的時候,只有當前場景對應使用的屬性會被賦值,調用模型類的validate()方法進行數據驗證的時候,只有當前場景屬性相關的且適用於當前場景的驗證規則會被執行。數組

 

2、驗證規則安全

        Yii模型類經過實現rules()方法申明使用的全部驗證規則,示例:

public function rules() {
        return [
            [['username', 'password'], 'required'],
            ['email', 'email', ‘on’ => ‘signup’]
        ];
}

         一條規則可適用於一個或多個場景,一條規則可用來驗證一個或多個屬性,一個屬性可對應一條或多條驗證規則。若是沒有指定’on’屬性,驗證規則會在全部場景下使用。

         全部的驗證規則均可以經過設置’message’屬性來自定義錯誤信息,並且在錯誤信息內容中能夠經過{attribute}來引用當前屬性標籤名稱(屬性標籤名稱須要在模型的attributeLabels()方法設置),經過{value}來引用當前屬性的輸入值,例如:

['username', 'unique', 'on' => 'register', 'message' => '{attribute}"{value}"已被佔用!', ‘on’ => ‘signup’]//註冊時用戶名惟一

         yii驗證的使用方式有如下三種:

1. 客戶端驗證:

         Yii默認開啓客戶端驗證,能夠經過設置enableClientValidation參數爲true開啓,開啓以後ActiveForm會讀取模型中申明的驗證規則生成相應的Javascript驗證代碼。enableClientValidation參數設置的方式有三種:

1)在視圖文件ActiveForm中對整個form進行設置:

<?php $form = ActiveForm::begin([
    'enableClientValidation' =>true
]); ?>

(2)在視圖文件ActiveField中對單個field進行設置:

<?= $form->field($model, 'username', ['enableClientValidation'=>false])->label('用戶名') ?>

3)在AR類的rules()函數中設置:

['username', 'yii\validators\StringValidator', 'min' => 3, 'max' => 30, 'enableClientValidation' => true, 'on' => 'register']

優先級:(2>1>3

2. 服務器端驗證

1validate()

         模型validate()方法會根據rules()方法中定義的驗證規則對全部數據進行驗證,驗證經過返回true,不然將錯誤保存在yii\base\Model::errors屬性中並返回false

2save()

         模型save()方法中默認調用validate()方法進行數據驗證,驗證經過則直接進行數據庫操做,返回true,不然不進行數據庫操做,返回false,將錯誤信息存儲在yii\base\Model::errors屬性中。若已顯式調用過validate(),能夠經過傳參避免在save()方法中重複驗證數據:save(false)

3. Ajax驗證:

          Yii默認關閉ajax驗證,能夠經過配置enableAjaxValidation參數爲true開啓。

客戶端設置(兩種方式):

1)在視圖文件ActiveForm中對整個form進行設置:

<?php $form = ActiveForm::begin([
    'enableAjaxValidation' =>true
]); ?>

2)在視圖文件ActiveField中對單個field進行設置:

<?= $form->field($model, 'username', ['enableAjaxValidation'=>false])->label('用戶名') ?>

優先級:(2>1

服務器端處理:

if(Yii::$app->request->isAjax) {
        $res = \yii\bootstrap\ActiveForm::validate($model);
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
        return $res;
}

注:有些驗證規則沒法使用客戶端驗證,如:uniqueexist等。

 

3、yii核心驗證器

         Yii提供了一些核心驗證器,能夠直接使用,申明格式以下:

[‘屬性名’, ‘驗證器名稱/類名’, ...(一些額外參數設置)]

瞭解並使用yii的核心驗證器會讓開發變得簡單許多。下面簡單對yii核心驗證器進行分類介紹。

1. 不進行數據驗證的驗證器

1safe:而是把一個屬性標記爲安全屬性。

[‘desc’, ‘safe’]

2default:給值爲空的屬性設置默認值。

[‘add_time', 'default', 'value' => time()]

3trim:去除輸入值首尾兩側多餘空格。

[‘username’, ‘trim’]

(4)filter:濾鏡,對數據進行格式化或一些其餘處理後返回。

[‘phone’, ‘filter’, ‘filter’ => function($value) {

         ....return $value;

}]

filter: 用於定義濾鏡的php回調函數,能夠爲全局函數名,匿名函數或其餘。

skipOnArray:是否在輸入爲數組時跳過濾鏡,默認爲false。若是濾鏡不能處理數組輸入,應該設置爲true。

2. 數據類型驗證器

1boolean:布爾型。

[‘del’, ‘boolean’, ‘trueValue’ => true, ‘falseValue’ => false, ‘strict’ => true]

trueValue:表明真的值,默認爲1

falseValue:表明假的值,默認爲0

strict:是否要求輸入數據必須嚴格匹配trueValuefalseValue。默認爲false

2number:數字。

[‘salary’, ‘number’]

3double:雙精度浮點型,等效於number驗證器。

[‘salary’,’double’, ‘max’ => 99.99, ‘min’ => 0]

4integer:整數。

[‘age’, ‘integer’]

注:numberdoubleinteger驗證器均可以設置minmax參數來限制數字的最大、最小值(含界點)。

5string:字符串。

[‘username’, ‘string’, ‘length’ => [3, 30]]

length:指定輸入字符串的長度限制。

min:字符串最小長度。

max:字符串最大長度。

encoding:字符串的編碼方式,不設置則使用應用自身的charset屬性值。默認爲utf-8

3. 數據格式驗證器

1date:日期。

[‘time’, ‘date’, ‘format’ => ‘php:Y:m:d’, ‘timestampAttribute’ => ‘startTime’]

format:時間格式,默認爲「y-m-d」。

timestampAttribute:將時間轉化爲時間戳並賦值給某個屬性。

2email:驗證是否符合郵箱地址格式。

[‘emailAddr’, ‘email’]

3ip:驗證是否爲有效IP地址。

[‘ip_address’, ‘ip’]

4url:網址。

[‘website’, ‘url’, ‘defaultScheme’ => ‘http’]

validSchemes:用於指定哪些URI方案會被視爲有效,默認爲[‘http’, ‘https’]

defaultScheme:若輸入值沒有對應的方案前綴,會使用的默認URI方案前綴。

5match:輸入值是否知足某個正則表達式。

[‘username’, ‘match’, ‘pattern’ => ‘/^[a-z]\w*$/i’]

pattern:正則表達式。

not:是否對驗證結果取反。

4. 數據值驗證器

1required:必填。

[[‘username’, ‘password’], ‘required’]

requiredValue:所指望的值,若沒設置則輸入不能爲空。

strict:檢查輸入值時是否檢查類型。

2captcha:驗證碼。

[‘verifyCode’, ‘captcha’, ‘caseSensitive’ => true, ‘captchaAction’ => ‘site/captcha’, ‘skipOnEmpty’ => false]

caseSensitive:是否大小寫敏感,默認爲false

captchaAction:指向用於渲染驗證碼圖片的captcha方法的路由,默認爲‘site/captcha’。

skipOnEmpty:輸入爲空時是否跳過驗證,默認爲false

3compare:比較。

[‘password’, ‘compare’, ‘compareAttribute’ => ‘conpassword’, ‘operator’ => ‘==’]

compareAttribute:與指定屬性值比較的屬性名稱。

compareValue:與某個常量值比較。

operator:比較操做符。

其中compareAttribute默認在驗證屬性後面加後綴「_repeat」做爲另外一個比較屬性的名稱,operator默認爲「==」,即:[‘password’, ‘compare’]規則表示驗證passwordpassword_repeat的值是否相等。

4each:驗證數組。

[‘ids’, ‘each’, ‘rule’ => [‘integer’]]

(驗證數組ids中的每一個元素是否都是int類型數據)

rule:定義驗證每個數組元素的驗證規則。

allowMessageFromRule:是否使用rule中指定的多個驗證規則報錯信息,默認爲true,若設置爲false,則使用「message」參數值做爲錯誤信息。

注:若輸入值不是數組則會報錯。

5exist:存在性。

 [‘cid’, ‘exist’, ‘targetClass’ => ‘app\models\Category’, ‘targetAttribute’ => ‘id’]

cid的值是否在AR類對應的id屬性中存在,使用場景:當前AR模型關聯的數據表的cid字段和Category模型關聯的數據表的id字段相關聯,因此使用該驗證規則驗證cid字段的值可否在關聯的另外一個數據表中找到對應記錄)

targetClass:用於查找輸入值的目標AR類。

targetAttribute:用於查找輸入值的目標屬性名稱。

filter:檢查屬性值存在性須要進行數據庫查詢,該參數設置查詢的過濾條件。能夠設置爲查詢條件的字符串或數組,或者

function($query)匿名函數。

allowArray:是否容許輸入值爲數組,默認爲false。若設置爲true,則數組的每一個元素都必須在目標字段中存在。若把targetAttribute設置爲多元素數組來驗證被測值在多字段中的存在性時,該屬性不能設置爲true

6unique:惟一性。

['email', 'unique', 'targetClass' => 'app\models\User', 'message' => '{attribute}"{value}"已被註冊!', 'on' => ‘signup’]

除了沒有allowArray屬性,其餘屬性都和exist驗證器同樣。

7in:範圍。

[‘sex’, ‘in’, ‘range’ => [0, 1, 2]]

range:範圍值列表。

strict:是否使用嚴格模式(類型與值都要相同)。

not:是否對驗證的結果取反,默認爲false

allowArray:是否接受輸入數組,默認爲false

5. 文件驗證器

1file:文件。

[‘pcImg’, ‘file’, ‘extensions’ => [‘png’, ‘jpg’, ‘gif’], ‘maxSize’ => 1024*1024]

extensions:可接受上傳的文件擴展名列表。

mimeTypes:可接受上傳的MIME類型列表。

minSize:文件大小下限。

maxSize:文件大小上限。

maxFiles:上傳文件個數上限,默認爲1。設置爲大於1時輸入值必須爲數組。

checkExtensionByMimeType:是否經過文件的MIME類型來判斷文件擴展,默認爲true。(2image:圖片。

[‘mbImg’, ‘image’ extensions => ‘png, ipg’, ‘minWidth’ => 100, ‘minHeight’ => 100]

該驗證器繼承自file驗證器,並支持額外屬性minWidthmaxWidthminHeightmaxHeight來設置圖片的最小、最大寬度和最小、最大高度。

 

4、其餘驗證器

1. 條件式驗證:

[‘state’, ‘required’, ‘when’ => function($model) {//只在country屬性值爲’USA’的時候state屬性值纔不能爲空
         return $model->country==’USA’;
}]

注:若須要支持客戶端驗證,則要配置’whenClient’屬性。

1. 自定義驗證器:

1)行內驗證器:一種以模型方法或匿名函數的形式定義的驗證器。

示例:

['conpassword', function($attribute, $params) {
         if($this->$attribute != $this->newpassword) {
                $this->addError($attribute, '確認密碼和新密碼不一致!');
        }
}]。

(固然這裏也可使用yii核心驗證器’compare’來實現)

注:行內驗證器不支持客戶端驗證。

2)獨立驗證器:

         獨立驗證器是繼承自yii\validators\Validator或其子類的類,能夠經過重寫validateAttribute()方法來實現驗證規則,若驗證失敗,能夠調用yii\base\Model::addError()方法來保存錯誤信息到模型內。

獨立驗證器示例:

namespace app\components;
use yii\validators\Validator;

class ConpasswordValidator extends Validator {

         public function init() {
                  parent::init();
                  $this->message = '確認密碼和密碼不一致!';
         }

         //服務器端驗證
         public function validateAttribute($model, $attribute) {
                  if($model->conpassword !== $model->password) {
                           $model->addError($attribute, $this->message);
                  }
         }

         //客戶端驗證
         public function clientValidateAttribute($model, $attribute, $view) {
                  $conpassword = json_encode($model->conpassword);
                  $message = json_encode($this->message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
         return <<<JS
if(value != $conpassword) {
         message.push($message);
}
JS;
                  return false;
         }
}

模型中使用示例:

['conpassword', ‘app\components\ConpasswordValidator’]

 

最後要注意,驗證規則申明的前後順序對驗證結果也是有影響的!

相關文章
相關標籤/搜索