首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Yii 框架表單模型與驗證機制詳解:CFormModel、CValidator 與規則定義

     編輯:PHP 綜合知識

Yii 表單模型 CFormModel 專為非持久化資料驗證設計,核心流程:屬性批量賦值 → 收集驗證器 → 執行驗證 → 錯誤收集。本文以登入表單為例,完整解析 rules() 定義、CValidator::createValidator() 工廠模式、內建與內聯驗證器區別、驗證執行流程與錯誤提取。

一、表單模型基本結構

class LoginForm extends CFormModel {
    public $username;
    public $password;
    public $rememberMe;

    public function rules() {
        return [
            ['username, password', 'required'],
            ['rememberMe', 'boolean'],
            ['password', 'authenticate'], // 內聯驗證器
        ];
    }

    public function authenticate($attribute, $params) {
        // 自定義驗證邏輯,失敗時 $this->addError($attribute, '訊息');
    }
}

二、控制器典型用法

$model = new LoginForm();
$model->attributes = $_POST['LoginForm']; // 批量賦值(觸發 setter)
if ($model->validate()) {
    // 驗證通過,處理登入
} else {
    $errors = $model->getErrors(); // 所有錯誤
    $firstError = $model->getError('username'); // 單一欄位首個錯誤
}

三、驗證器建立流程:createValidator()

public static function createValidator($name, $object, $attributes, $params = []) {
    // 1. 正規化屬性陣列
    if (is_string($attributes)) $attributes = preg_split('/[\s,]+/', $attributes, -1, PREG_SPLIT_NO_EMPTY);
    // 2. 正規化場景 on
    if (isset($params['on'])) { /* ... */ }

    // 3. 判斷是內聯驗證器(模型有同名方法)還是獨立驗證器類別
    if (method_exists($object, $name)) {
        $validator = new CInlineValidator;
        $validator->attributes = $attributes;
        $validator->method = $name;
        $validator->params = $params;
        // clientValidate, skipOnError 等參數處理
    } else {
        // 4. 解析類別名:內建對照表 或 完整類別路徑
        if (isset(self::$builtInValidators[$name]))
            $className = Yii::import(self::$builtInValidators[$name], true);
        else
            $className = Yii::import($name, true);
        $validator = new $className;
        foreach ($params as $k => $v) $validator->$k = $v;
    }
    $validator->on = empty($on) ? [] : array_combine($on, $on);
    return $validator;
}

四、內建驗證器對照表(節選)

規則名稱對應類別說明
requiredCRequiredValidator必填
emailCEmailValidatorEmail 格式
urlCUrlValidatorURL 格式
matchCRegularExpressionValidator正則匹配
compareCCompareValidator比較(相等、大小等)
numericalCNumberValidator數值型別
lengthCStringValidator字串長度
booleanCBooleanValidator布林值
dateCDateValidator日期格式
typeCTypeValidator型別轉換驗證
uniqueCUniqueValidator資料庫唯一性(AR 專用)
existCExistValidator資料庫存在性(AR 專用)

五、驗證執行與場景

  • $model->validate():執行所有屬於當前 scenario 的驗證器。
  • $model->validate(['username']):僅驗證指定屬性。
  • 場景控制:rules() 陣列可加 'on' => 'scenarioName',模型 $model->scenario = 'scenarioName' 切換。
  • skipOnError:同屬性多驗證器,前一個失敗是否跳過後續(預設 true)。

六、客戶端驗證支援

內建驗證器實作 clientValidateAttribute() 產生 JS 代碼,配合 CHtml::activeForm() enableClientValidation=true 實現前端即時驗證,減少伺服器負載。

七、常見錯誤與最佳實踐

  • 屬性未宣告 public:attributes 批量賦值只能設定 safe 屬性(出現在 rules 中),未宣告屬性會被忽略。
  • 內聯驗證器未回傳布林:慣例不需回傳值,透過 $this->addError() 標記失敗。
  • 驗證器參數傳遞:['attr', 'validator', 'param1' => 'val'] 從第 3 元素起進入 $params。
  • 避免在 rules 閉包中使用 $this:PHP 5.3 閉包需 use ($model) 或改用獨立驗證器類別。

小結

Yii 表單驗證核心在於 rules() 宣告式定義 + CValidator 工廠建立 + validate() 統一執行。掌握內建/內聯/自訂驗證器三種形式、場景控制、客戶端驗證整合,即能構建健壯且可維護的表單驗證體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved