亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄 搜索
閱讀前篇 簡(jiǎn)介 Yii 是什么 從 Yii 1.1 升級(jí) 入門 安裝 Yii 運(yùn)行應(yīng)用 第一次問候 使用Forms 數(shù)據(jù)庫(kù)應(yīng)用 使用 Gii 生成代碼 進(jìn)階 應(yīng)用結(jié)構(gòu) 概述 入口腳本 應(yīng)用(Applications) 應(yīng)用組件(Application Components) 控制器(Controllers) 模型(Models) 視圖(views) 模塊(Modules) 過濾器(Filters) 小部件(Widgets) 前端資源(Assets) 擴(kuò)展(Extensions) 請(qǐng)求處理 運(yùn)行概述 啟動(dòng)引導(dǎo)(Bootstrapping) 路由和創(chuàng)建URL 請(qǐng)求(Requests) 響應(yīng)(Responses) Sessions 和 Cookies 錯(cuò)誤處理(Handling Errors) 日志(Logging) 關(guān)鍵概念 組件(Component) 屬性(Property) 事件(Events) 行為(Behaviors) 配置(Configurations) 別名(Aliases) 類自動(dòng)加載(Autoloading) 服務(wù)定位器(Service Locator) 依賴注入容器(Dependency Injection Container) 配合數(shù)據(jù)庫(kù)工作 數(shù)據(jù)庫(kù)訪問 (Data Access Objects) 查詢生成器(Query Builder) 活動(dòng)記錄(Active Record) 數(shù)據(jù)庫(kù)遷移(Migrations) Sphinx Redis MongoDB Elasticsearch 接收用戶數(shù)據(jù) 創(chuàng)建表單(Creating Forms) 輸入驗(yàn)證(Validating Input) 文件上傳(Uploading Files) 收集列表輸入(Collecting Tabular Input) 多模型的復(fù)合表單(Getting Data for Multiple Models) 顯示數(shù)據(jù) 格式化輸出數(shù)據(jù)(Data Formatting) 分頁(yè)(Pagination) 排序(Sorting) 數(shù)據(jù)提供器(Data Providers) 數(shù)據(jù)小部件(Data Widgets) 客戶端腳本使用(Working with Client Scripts) 主題(Theming) 安全 認(rèn)證(Authentication) 授權(quán)(Authorization) 處理密碼(Working with Passwords) 客戶端認(rèn)證(Auth Clients) 最佳安全實(shí)踐(Best Practices) 緩存 概述 數(shù)據(jù)緩存 片段緩存 頁(yè)面緩存 HTTP 緩存 RESTfull Web服務(wù) 快速入門(Quick Start) 資源(Resources) 控制器(Controllers) 路由(Routing) 格式化響應(yīng)(Response Formatting) 授權(quán)認(rèn)證(Authentication) 速率限制(Rate Limiting) 版本(Versioning) 錯(cuò)誤處理(Error Handling) 開發(fā)工具 調(diào)試工具欄和調(diào)試器 使用Gii生成代碼 生成API文檔 測(cè)試 概述(Overview) 配置測(cè)試環(huán)境(Testing environment setup) 單元測(cè)試(Unit Tests) 功能測(cè)試(Function Tests) 驗(yàn)收測(cè)試(Acceptance Tests) 測(cè)試夾具(Fixtures) 高級(jí)專題 高級(jí)應(yīng)用模板 創(chuàng)建自定義應(yīng)用程序結(jié)構(gòu) 控制臺(tái)命令 核心驗(yàn)證器(Core Validators) 國(guó)際化 收發(fā)郵件 性能優(yōu)化 共享主機(jī)環(huán)境 模板引擎 集成第三方代碼 小部件 Bootstrap 小部件 Jquery UI 助手類 概述 Array 助手(ArrayHelper) Html 助手(Html) Url 助手(Url)
文字

輸入驗(yàn)證

輸入驗(yàn)證

一般說來(lái),程序猿永遠(yuǎn)不應(yīng)該信任從最終用戶直接接收到的數(shù)據(jù),并且使用它們之前應(yīng)始終先驗(yàn)證其可靠性。

要給?model?填充其所需的用戶輸入數(shù)據(jù),你可以調(diào)用 yii\base\Model::validate() 方法驗(yàn)證它們。該方法會(huì)返回一個(gè)布爾值,指明是否通過驗(yàn)證。若沒有通過,你能通過 yii\base\Model::errors 屬性獲取相應(yīng)的報(bào)錯(cuò)信息。比如,

$model = new \app\models\ContactForm;

// 用用戶輸入來(lái)填充模型的特性$model->attributes = \Yii::$app->request->post('ContactForm');

if ($model->validate()) {
    // 若所有輸入都是有效的
} else {
    // 有效性驗(yàn)證失敗:$errors 屬性就是存儲(chǔ)錯(cuò)誤信息的數(shù)組
    $errors = $model->errors;
}

validate()?方法,在幕后為執(zhí)行驗(yàn)證操作,進(jìn)行了以下步驟:

  1. 通過從 yii\base\Model::scenarios() 方法返回基于當(dāng)前 yii\base\Model::scenario 的特性屬性列表,算出哪些特性應(yīng)該進(jìn)行有效性驗(yàn)證。這些屬性被稱作?active attributes(激活特性)。
  2. 通過從 yii\base\Model::rules() 方法返回基于當(dāng)前 yii\base\Model::scenario 的驗(yàn)證規(guī)則列表,這些規(guī)則被稱作?active rules(激活規(guī)則)。
  3. 用每個(gè)激活規(guī)則去驗(yàn)證每個(gè)與之關(guān)聯(lián)的激活特性。若失敗,則記錄下對(duì)應(yīng)模型特性的錯(cuò)誤信息。

聲明規(guī)則(Rules)

要讓?validate()?方法起作用,你需要聲明與需驗(yàn)證模型特性相關(guān)的驗(yàn)證規(guī)則。為此,需要重寫 yii\base\Model::rules() 方法。下面的例子展示了如何聲明用于驗(yàn)證?ContactForm?模型的相關(guān)驗(yàn)證規(guī)則:

public function rules(){
    return [
        // name,email,subject 和 body 特性是 `require`(必填)的
        [['name', 'email', 'subject', 'body'], 'required'],

        // email 特性必須是一個(gè)有效的 email 地址
        ['email', 'email'],
    ];
}

yii\base\Model::rules() 方法應(yīng)返回一個(gè)由規(guī)則所組成的數(shù)組,每一個(gè)規(guī)則都呈現(xiàn)為以下這類格式的小數(shù)組:

[
    // 必須項(xiàng),用于指定那些模型特性需要通過此規(guī)則的驗(yàn)證。
    // 對(duì)于只有一個(gè)特性的情況,可以直接寫特性名,而不必用數(shù)組包裹。
    ['attribute1', 'attribute2', ...],

    // 必填項(xiàng),用于指定規(guī)則的類型。
    // 它可以是類名,驗(yàn)證器昵稱,或者是驗(yàn)證方法的名稱。
    'validator',

    // 可選項(xiàng),用于指定在場(chǎng)景(scenario)中,需要啟用該規(guī)則
    // 若不提供,則代表該規(guī)則適用于所有場(chǎng)景
    // 若你需要提供除了某些特定場(chǎng)景以外的所有其他場(chǎng)景,你也可以配置 "except" 選項(xiàng)
    'on' => ['scenario1', 'scenario2', ...],

    // 可選項(xiàng),用于指定對(duì)該驗(yàn)證器對(duì)象的其他配置選項(xiàng)
    'property1' => 'value1', 'property2' => 'value2', ...
]

對(duì)于每個(gè)規(guī)則,你至少需要指定該規(guī)則適用于哪些特性,以及本規(guī)則的類型是什么。你可以指定以下的規(guī)則類型之一:

  • 核心驗(yàn)證器的昵稱,比如?required、in、date,等等。請(qǐng)參考核心驗(yàn)證器章節(jié)查看完整的核心驗(yàn)證器列表。
  • 模型類中的某個(gè)驗(yàn)證方法的名稱,或者一個(gè)匿名方法。請(qǐng)參考行內(nèi)驗(yàn)證器小節(jié)了解更多。
  • 驗(yàn)證器類的名稱。請(qǐng)參考獨(dú)立驗(yàn)證器小節(jié)了解更多。

一個(gè)規(guī)則可用于驗(yàn)證一個(gè)或多個(gè)模型特性,且一個(gè)特性可以被一個(gè)或多個(gè)規(guī)則所驗(yàn)證。一個(gè)規(guī)則可以施用于特定場(chǎng)景(scenario),只要指定?on?選項(xiàng)。如果你不指定?on?選項(xiàng),那么該規(guī)則會(huì)適配于所有場(chǎng)景。

當(dāng)調(diào)用?validate()?方法時(shí),它將運(yùn)行以下幾個(gè)具體的驗(yàn)證步驟:

  1. 檢查從聲明自 yii\base\Model::scenarios() 方法的場(chǎng)景中所挑選出的當(dāng)前yii\base\Model::scenario的信息,從而確定出那些特性需要被驗(yàn)證。這些特性被稱為激活特性。
  2. 檢查從聲明自 yii\base\Model::rules() 方法的眾多規(guī)則中所挑選出的適用于當(dāng)前yii\base\Model::scenario的規(guī)則,從而確定出需要驗(yàn)證哪些規(guī)則。這些規(guī)則被稱為激活規(guī)則。
  3. 用每個(gè)激活規(guī)則去驗(yàn)證每個(gè)與之關(guān)聯(lián)的激活特性。

基于以上驗(yàn)證步驟,有且僅有聲明在?scenarios()?方法里的激活特性,且它還必須與一或多個(gè)聲明自?rules()?里的激活規(guī)則相關(guān)聯(lián)才會(huì)被驗(yàn)證。

自定義錯(cuò)誤信息

大多數(shù)的驗(yàn)證器都有默認(rèn)的錯(cuò)誤信息,當(dāng)模型的某個(gè)特性驗(yàn)證失敗的時(shí)候,該錯(cuò)誤信息會(huì)被返回給模型。比如,用 yii\validators\RequiredValidator 驗(yàn)證器的規(guī)則檢驗(yàn)?username?特性失敗的話,會(huì)返還給模型 "Username cannot be blank." 信息。

你可以通過在聲明規(guī)則的時(shí)候同時(shí)指定?message?屬性,來(lái)定制某個(gè)規(guī)則的錯(cuò)誤信息,比如這樣:

public function rules(){
    return [
        ['username', 'required', 'message' => 'Please choose a username.'],
    ];
}

一些驗(yàn)證器還支持用于針對(duì)不同原因的驗(yàn)證失敗返回更加準(zhǔn)確的額外錯(cuò)誤信息。比如,yii\validators\NumberValidator 驗(yàn)證器就支持 yii\validators\NumberValidator::tooBig 和 yii\validators\NumberValidator::tooSmall 兩種錯(cuò)誤消息用于分別返回輸入值是太大還是太小。 你也可以像配置驗(yàn)證器的其他屬性一樣配置它們倆各自的錯(cuò)誤信息。

驗(yàn)證事件

當(dāng)調(diào)用 yii\base\Model::validate() 方法的過程里,它同時(shí)會(huì)調(diào)用兩個(gè)特殊的方法,把它們重寫掉可以實(shí)現(xiàn)自定義驗(yàn)證過程的目的:

  • yii\base\Model::beforeValidate():在默認(rèn)的實(shí)現(xiàn)中會(huì)觸發(fā) yii\base\Model::EVENT_BEFORE_VALIDATE 事件。你可以重寫該方法或者響應(yīng)此事件,來(lái)在驗(yàn)證開始之前,先進(jìn)行一些預(yù)處理的工作。(比如,標(biāo)準(zhǔn)化數(shù)據(jù)輸入)該方法應(yīng)該返回一個(gè)布爾值,用于標(biāo)明驗(yàn)證是否通過。
  • yii\base\Model::afterValidate():在默認(rèn)的實(shí)現(xiàn)中會(huì)觸發(fā) yii\base\Model::EVENT_AFTER_VALIDATE 事件。你可以重寫該方法或者響應(yīng)此事件,來(lái)在驗(yàn)證結(jié)束之后,再進(jìn)行一些收尾的工作。

條件式驗(yàn)證

若要只在某些條件滿足時(shí),才驗(yàn)證相關(guān)特性,比如:是否驗(yàn)證某特性取決于另一特性的值,你可以通過 yii\validators\Validator::when 屬性來(lái)定義相關(guān)條件。舉例而言,

[
    ['state', 'required', 'when' => function($model) {
        return $model->country == 'USA';
    }],
]

yii\validators\Validator::when 屬性會(huì)讀入一個(gè)如下所示結(jié)構(gòu)的 PHP callable 函數(shù)對(duì)象:

function ($model, $attribute)

若你需要支持客戶端的條件驗(yàn)證,你應(yīng)該配置 yii\validators\Validator::whenClient 屬性,它會(huì)讀入一條包含有 JavaScript 函數(shù)的字符串。這個(gè)函數(shù)將被用于確定該客戶端驗(yàn)證規(guī)則是否被啟用。比如,

[
    ['state', 'required', 'when' => function ($model) {
        return $model->country == 'USA';
    }, 'whenClient' => "function (attribute, value) {
        return $('#country').value == 'USA';
    }"],
]

數(shù)據(jù)預(yù)處理

用戶輸入經(jīng)常需要進(jìn)行數(shù)據(jù)過濾,或者叫預(yù)處理。比如你可能會(huì)需要先去掉?username?輸入的收尾空格。你可以通過使用驗(yàn)證規(guī)則來(lái)實(shí)現(xiàn)此目的。

下面的例子展示了如何去掉輸入信息的首尾空格,并將空輸入返回為 null。具體方法為通過調(diào)用?trim?和?default?核心驗(yàn)證器:

[
    [['username', 'email'], 'trim'],
    [['username', 'email'], 'default'],
]

也還可以用更加通用的?filter(濾鏡)?核心驗(yàn)證器來(lái)執(zhí)行更加復(fù)雜的數(shù)據(jù)過濾。

如你所見,這些驗(yàn)證規(guī)則并不真的對(duì)輸入數(shù)據(jù)進(jìn)行任何驗(yàn)證。而是,對(duì)輸入數(shù)據(jù)進(jìn)行一些處理,然后把它們存回當(dāng)前被驗(yàn)證的模型特性。

處理空輸入

當(dāng)輸入數(shù)據(jù)是通過 HTML 表單,你經(jīng)常會(huì)需要給空的輸入項(xiàng)賦默認(rèn)值。你可以通過調(diào)整?default?驗(yàn)證器來(lái)實(shí)現(xiàn)這一點(diǎn)。舉例來(lái)說,

[
    // 若 "username" 和 "email" 為空,則設(shè)為 null
    [['username', 'email'], 'default'],

    // 若 "level" 為空,則設(shè)其為 1
    ['level', 'default', 'value' => 1],
]

默認(rèn)情況下,當(dāng)輸入項(xiàng)為空字符串,空數(shù)組,或 null 時(shí),會(huì)被視為“空值”。你也可以通過配置 yii\validators\Validator::isEmpty 屬性來(lái)自定義空值的判定規(guī)則。比如,

[
    ['agree', 'required', 'isEmpty' => function ($value) {
        return empty($value);
    }],
]

注意:對(duì)于絕大多數(shù)驗(yàn)證器而言,若其 yii\base\Validator::skipOnEmpty 屬性為默認(rèn)值 true,則它們不會(huì)對(duì)空值進(jìn)行任何處理。也就是當(dāng)他們的關(guān)聯(lián)特性接收到空值時(shí),相關(guān)驗(yàn)證會(huì)被直接略過。在?核心驗(yàn)證器?之中,只有?captcha(驗(yàn)證碼),default(默認(rèn)值),filter(濾鏡),required(必填),以及?trim(去首尾空格),這幾個(gè)驗(yàn)證器會(huì)處理空輸入。

臨時(shí)驗(yàn)證

有時(shí),你需要對(duì)某些沒有綁定任何模型類的值進(jìn)行?臨時(shí)驗(yàn)證。

若你只需要進(jìn)行一種類型的驗(yàn)證 (e.g. 驗(yàn)證郵箱地址),你可以調(diào)用所需驗(yàn)證器的 yii\validators\Validator::validate() 方法。像這樣:

$email = 'test@example.com';
$validator = new yii\validators\EmailValidator();

if ($validator->validate($email, $error)) {
    echo '有效的 Email 地址。';
} else {
    echo $error;
}

注意:不是所有的驗(yàn)證器都支持這種形式的驗(yàn)證。比如?unique(唯一性)核心驗(yàn)證器就就是一個(gè)例子,它的設(shè)計(jì)初衷就是只作用于模型類內(nèi)部的。

若你需要針對(duì)一系列值執(zhí)行多項(xiàng)驗(yàn)證,你可以使用 yii\base\DynamicModel 。它支持即時(shí)添加特性和驗(yàn)證規(guī)則的定義。它的使用規(guī)則是這樣的:

public function actionSearch($name, $email){
    $model = DynamicModel::validateData(compact('name', 'email'), [
        [['name', 'email'], 'string', 'max' => 128],
        ['email', 'email'],
    ]);

    if ($model->hasErrors()) {
        // 驗(yàn)證失敗
    } else {
        // 驗(yàn)證成功
    }
}

yii\base\DynamicModel::validateData() 方法會(huì)創(chuàng)建一個(gè)?DynamicModel?的實(shí)例對(duì)象,并通過給定數(shù)據(jù)定義模型特性(以?name?和?email為例),之后用給定規(guī)則調(diào)用 yii\base\Model::validate() 方法。

除此之外呢,你也可以用如下的更加“傳統(tǒng)”的語(yǔ)法來(lái)執(zhí)行臨時(shí)數(shù)據(jù)驗(yàn)證:

public function actionSearch($name, $email){
    $model = new DynamicModel(compact('name', 'email'));
    $model->addRule(['name', 'email'], 'string', ['max' => 128])
        ->addRule('email', 'email')
        ->validate();

    if ($model->hasErrors()) {
        // 驗(yàn)證失敗
    } else {
        // 驗(yàn)證成功
    }
}

驗(yàn)證之后你可以通過調(diào)用 yii\base\DynamicModel::hasErrors() 方法來(lái)檢查驗(yàn)證通過與否,并通過 yii\base\DynamicModel::errors 屬性獲得驗(yàn)證的錯(cuò)誤信息,過程與普通模型類一致。你也可以訪問模型對(duì)象內(nèi)定義的動(dòng)態(tài)特性,就像:?$model->name?和?$model->email。

創(chuàng)建驗(yàn)證器(Validators)

除了使用 Yii 的發(fā)布版里所包含的核心驗(yàn)證器之外,你也可以創(chuàng)建你自己的驗(yàn)證器。自定義的驗(yàn)證器可以是行內(nèi)驗(yàn)證器,也可以是獨(dú)立驗(yàn)證器。

行內(nèi)驗(yàn)證器(Inline Validators)

行內(nèi)驗(yàn)證器是一種以模型方法或匿名函數(shù)的形式定義的驗(yàn)證器。這些方法/函數(shù)的結(jié)構(gòu)如下:

function ($attribute, $params)

若某特性的驗(yàn)證失敗了,該方法/函數(shù)應(yīng)該調(diào)用 yii\base\Model::addError() 保存錯(cuò)誤信息到模型內(nèi)。這樣這些錯(cuò)誤就能在之后的操作中,被讀取并展現(xiàn)給終端用戶。

下面是一些例子:

use yii\base\Model;

class MyForm extends Model{
    public $country;
    public $token;

    public function rules()
    {
        return [
            // 以模型方法 validateCountry() 形式定義的行內(nèi)驗(yàn)證器
            ['country', 'validateCountry'],

            // 以匿名函數(shù)形式定義的行內(nèi)驗(yàn)證器
            ['token', function ($attribute, $params) {
                if (!ctype_alnum($this->$attribute)) {
                    $this->addError($attribute, 'token 本身必須包含字母或數(shù)字。');
                }
            }],
        ];
    }

    public function validateCountry($attribute, $params)
    {
        if (!in_array($this->$attribute, ['USA', 'Web'])) {
            $this->addError($attribute, 'The country must be either "USA" or "Web".');
        }
    }
}

注意:缺省狀態(tài)下,行內(nèi)驗(yàn)證器不會(huì)在關(guān)聯(lián)特性的輸入值為空或該特性已經(jīng)在其他驗(yàn)證中失敗的情況下起效。若你想要確保該驗(yàn)證器始終啟用的話,你可以在定義規(guī)則時(shí),酌情將 yii\validators\Validator::skipOnEmpty 以及 yii\validators\Validator::skipOnError 屬性設(shè)為 false,比如,?`php [

['country', 'validateCountry', 'skipOnEmpty' => false, 'skipOnError' => false],

]?`

獨(dú)立驗(yàn)證器(Standalone Validators)

獨(dú)立驗(yàn)證器是繼承自 yii\validators\Validator 或其子類的類。你可以通過重寫 yii\validators\Validator::validateAttribute() 來(lái)實(shí)現(xiàn)它的驗(yàn)證規(guī)則。若特性驗(yàn)證失敗,可以調(diào)用 yii\base\Model::addError() 以保存錯(cuò)誤信息到模型內(nèi),操作與?inline validators?所需操作完全一樣。比如,

namespace app\components;

use yii\validators\Validator;

class CountryValidator extends Validator{
    public function validateAttribute($model, $attribute)
    {
        if (!in_array($model->$attribute, ['USA', 'Web'])) {
            $this->addError($attribute, 'The country must be either "USA" or "Web".');
        }
    }
}

若你想要驗(yàn)證器支持不使用 model 的數(shù)據(jù)驗(yàn)證,你還應(yīng)該重寫 yii\validators\Validator::validate() 方法。你也可以通過重寫 yii\validators\Validator::validateValue() 方法替代?validateAttribute()?和?validate(),因?yàn)槟J(rèn)狀態(tài)下,后兩者的實(shí)現(xiàn)使用過調(diào)用validateValue()實(shí)現(xiàn)的。

客戶端驗(yàn)證器(Client-Side Validation)

當(dāng)終端用戶通過 HTML 表單提供相關(guān)輸入信息時(shí),我們可能會(huì)需要用到基于 JavaScript 的客戶端驗(yàn)證。因?yàn)?,它可以讓用戶更快速的得到錯(cuò)誤信息,也因此可以提供更好的用戶體驗(yàn)。你可以使用或自己實(shí)現(xiàn)除服務(wù)器端驗(yàn)證之外,還能額外客戶端驗(yàn)證功能的驗(yàn)證器。

補(bǔ)充:盡管客戶端驗(yàn)證為加分項(xiàng),但它不是必須項(xiàng)。它存在的主要意義在于給用戶提供更好的客戶體驗(yàn)。正如“永遠(yuǎn)不要相信來(lái)自終端用戶的輸入信息”,也同樣永遠(yuǎn)不要相信客戶端驗(yàn)證?;谶@個(gè)理由,你應(yīng)該始終如前文所描述的那樣,通過調(diào)用 yii\base\Model::validate() 方法執(zhí)行服務(wù)器端驗(yàn)證。

使用客戶端驗(yàn)證

許多核心驗(yàn)證器都支持開箱即用的客戶端驗(yàn)證。你只需要用 yii\widgets\ActiveForm 的方式構(gòu)建 HTML 表單即可。比如,下面的LoginForm(登錄表單)聲明了兩個(gè)規(guī)則:其一為?required?核心驗(yàn)證器,它同時(shí)支持客戶端與服務(wù)器端的驗(yàn)證;另一個(gè)則采用validatePassword?行內(nèi)驗(yàn)證器,它只支持服務(wù)器端。

namespace app\models;

use yii\base\Model;
use app\models\User;

class LoginForm extends Model{
    public $username;
    public $password;

    public function rules()
    {
        return [
            // username 和 password 都是必填項(xiàng)
            [['username', 'password'], 'required'],

            // 用 validatePassword() 驗(yàn)證 password
            ['password', 'validatePassword'],
        ];
    }

    public function validatePassword()
    {
        $user = User::findByUsername($this->username);

        if (!$user || !$user->validatePassword($this->password)) {
            $this->addError('password', 'Incorrect username or password.');
        }
    }
}

使用如下代碼構(gòu)建的 HTML 表單包含兩個(gè)輸入框?username?以及?password。如果你在沒有輸入任何東西之前提交表單,就會(huì)在沒有任何與服務(wù)器端的通訊的情況下,立刻收到一個(gè)要求你填寫空白項(xiàng)的錯(cuò)誤信息。

<?php $form = yii\widgets\ActiveForm::begin(); ?>
    <?= $form->field($model, 'username') ?>
    <?= $form->field($model, 'password')->passwordInput() ?>
    <?= Html::submitButton('Login') ?><?php yii\widgets\ActiveForm::end(); ?>

幕后的運(yùn)作過程是這樣的:yii\widgets\ActiveForm 會(huì)讀取聲明在模型類中的驗(yàn)證規(guī)則,并生成那些支持支持客戶端驗(yàn)證的驗(yàn)證器所需的 JavaScript 代碼。當(dāng)用戶修改輸入框的值,或者提交表單時(shí),就會(huì)觸發(fā)相應(yīng)的客戶端驗(yàn)證 JS 代碼。

若你需要完全關(guān)閉客戶端驗(yàn)證,你只需配置 yii\widgets\ActiveForm::enableClientValidation 屬性為 false。你同樣可以關(guān)閉各個(gè)輸入框各自的客戶端驗(yàn)證,只要把它們的 yii\widgets\ActiveField::enableClientValidation 屬性設(shè)為 false。

自己實(shí)現(xiàn)客戶端驗(yàn)證

要穿件一個(gè)支持客戶端驗(yàn)證的驗(yàn)證器,你需要實(shí)現(xiàn) yii\validators\Validator::clientValidateAttribute() 方法,用于返回一段用于運(yùn)行客戶端驗(yàn)證的 JavaScript 代碼。在這段 JavaScript 代碼中,你可以使用以下預(yù)定義的變量:

  • attribute:正在被驗(yàn)證的模型特性的名稱。
  • value:進(jìn)行驗(yàn)證的值。
  • messages:一個(gè)用于暫存模型特性的報(bào)錯(cuò)信息的數(shù)組。

在下面的例子里,我們會(huì)創(chuàng)建一個(gè)?StatusValidator,它會(huì)通過比對(duì)現(xiàn)有的狀態(tài)數(shù)據(jù),驗(yàn)證輸入值是否為一個(gè)有效的狀態(tài)。該驗(yàn)證器同時(shí)支持客戶端以及服務(wù)器端驗(yàn)證。

namespace app\components;

use yii\validators\Validator;
use app\models\Status;

class StatusValidator extends Validator{
    public function init()
    {
        parent::init();
        $this->message = '無(wú)效的狀態(tài)輸入。';
    }

    public function validateAttribute($model, $attribute)
    {
        $value = $model->$attribute;
        if (!Status::find()->where(['id' => $value])->exists()) {
            $model->addError($attribute, $this->message);
        }
    }

    public function clientValidateAttribute($model, $attribute, $view)
    {
        $statuses = json_encode(Status::find()->select('id')->asArray()->column());
        $message = json_encode($this->message);
        return <<<JS
if (!$.inArray(value, $statuses)) {
    messages.push($message);
}
JS;
    }
}
技巧:上述代碼主要是演示了如何支持客戶端驗(yàn)證。在具體實(shí)踐中,你可以使用?in?核心驗(yàn)證器來(lái)達(dá)到同樣的目的。比如這樣的驗(yàn)證規(guī)則:

php [
?????['status',?'in',?'range'?=>?Status::find()->select('id')->asArray()->column()],
]

上一篇: 下一篇: