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

Yii CActiveForm AJAX 驗證完整實戰:表單配置、控制器響應、客戶端/服務端雙重驗證最佳實踐

     編輯:PHP 相關知識

Yii CActiveForm AJAX 驗證完整實戰:表單配置、控制器響應、客戶端/服務端雙重驗證最佳實踐

即時表單驗證極大提升用戶體驗。本文展示 Yii 1.x 利用 CActiveForm 實現 AJAX 異步驗證的完整配置:視圖啟用、控制器處理、模型規則、錯誤顯示與性能優化。

1. 視圖層:啟用 AJAX 驗證

<?php
$form = $this->beginWidget('CActiveForm', array(
    'id' => 'zdzone-form',                    // 表單 ID (必須,AJAX 識別用)
    'enableAjaxValidation' => true,           // 核心:開啟 AJAX 驗證
    'enableClientValidation' => true,         // 同時開啟客戶端 JS 驗證 (雙重保障)
    'action' => '/manage/adzone/createadzone', // 提交地址
    'htmlOptions' => array('class' => 'form-horizontal'),
)); 
?>

<div class="form-group">
    <?php echo $form->labelEx($model, 'name', array('class' => 'col-sm-2 control-label')); ?>
    <div class="col-sm-10">
        <?php echo $form->textField($model, 'name', array('class' => 'form-control')); ?>
        <?php echo $form->error($model, 'name', array('class' => 'text-danger')); ?>
    </div>
</div>

<div class="form-group">
    <?php echo $form->labelEx($model, 'url', array('class' => 'col-sm-2 control-label')); ?>
    <div class="col-sm-10">
        <?php echo $form->textField($model, 'url', array('class' => 'form-control')); ?>
        <?php echo $form->error($model, 'url', array('class' => 'text-danger')); ?>
    </div>
</div>

<div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
        <?php echo CHtml::submitButton('提交', array('class' => 'btn btn-primary')); ?>
    </div>
</div>

<?php $this->endWidget(); ?>

2. 控制器層:處理 AJAX 驗證請求

<?php
class AdzoneController extends Controller {
    public function actionCreateadzone() {
        $model = new AdZone();
        
        // 【關鍵】AJAX 驗證攔截:必須在模型賦值/保存之前
        if (isset($_POST['ajax']) && $_POST['ajax'] === 'zdzone-form') {
            echo CActiveForm::validate($model);
            Yii::app()->end(); // 直接輸出 JSON 錯誤信息,不渲染視圖
        }
        
        // 正常表單提交處理
        if (isset($_POST['AdZone'])) {
            $model->attributes = $_POST['AdZone'];
            if ($model->validate()) { // 服務端二次驗證 (防繞過 AJAX)
                if ($model->save()) {
                    $this->redirect(array('view', 'id' => $model->id));
                }
            }
        }
        
        $this->render('create', array('model' => $model));
    }
}

3. 模型層:驗證規則定義

<?php
class AdZone extends CActiveRecord {
    public function rules() {
        return array(
            array('name, url', 'required', 'message' => '{attribute} 不能為空'),
            array('name', 'length', 'max' => 100, 'tooLong' => '名稱最長 100 字符'),
            array('url', 'url', 'pattern' => '/^(https?:\/\/).+/i', 'message' => 'URL 格式不正確'),
            array('url', 'unique', 'message' => '該廣告位鏈接已存在'),
            array('status', 'in', 'range' => array(0, 1), 'message' => '狀態值非法'),
            // 安全屬性:允許批量賦值
            array('name, url, status', 'safe', 'on' => 'search'),
        );
    }
    
    public function attributeLabels() {
        return array(
            'name' => '廣告位名稱',
            'url' => '落地頁鏈接',
            'status' => '狀態',
        );
    }
}

4. 核心流程時序圖

用戶輸入字段 → 失去焦點 (blur) 
    ↓
jQuery.yii.activeForm.validate() 發送 POST
    ↓
POST /createadzone?ajax=zdzone-form
    ↓
控制器識別 $_POST['ajax'] === 'zdzone-form'
    ↓
CActiveForm::validate($model) 執行模型驗證
    ↓
返回 JSON: {"fieldId":["錯誤信息1","錯誤信息2"],...}
    ↓
前端更新對應字段 error 容器顯示紅字
    ↓
用戶修正後再次觸發驗證 → 綠勾/清空錯誤

5. 關鍵配置參數詳解

參數默認值說明
enableAjaxValidationfalse總開關
enableClientValidationfalse基於模型 rules 生成 JS 驗證代碼 (required、length、email、url、number、compare、custom)
validateOnSubmittrue提交時觸發 AJAX 驗證,失敗阻止提交
validateOnChangetrue值改變時觸發
validateOnTypefalse輸入時實時驗證 (高頻請求,慎開)
validationDelay200防抖延遲毫秒數
clientOptions.validateOnBlurtrue失焦驗證
clientOptions.afterValidatenullJS 回調:function(form, data, hasError) {}
clientOptions.afterValidateAttributenull單字段驗證後回調

6. 進階:自定義 AJAX 驗證回調

$form = $this->beginWidget('CActiveForm', array(
    'id' => 'custom-form',
    'enableAjaxValidation' => true,
    'clientOptions' => array(
        'afterValidateAttribute' => 'js:function(form, attribute, data, hasError) {
            if (!hasError) {
                $(attribute.container).addClass("has-success").removeClass("has-error");
                $(attribute.input).tooltip("destroy");
            } else {
                $(attribute.container).addClass("has-error").removeClass("has-success");
                $(attribute.input).tooltip({title: data[0], placement: "right"}).tooltip("show");
            }
        }',
    ),
));

7. 性能優化與避坑指南

問題原因解決
AJAX 請求過多validateOnType=true + 快速輸入關閉 validateOnType,依賴 validateOnBlur + validationDelay=500
驗證邏輯重複執行客戶端+服務端雙重客戶端僅做格式/必填,複雜業務規則 (唯一性、關聯檢查) 僅服務端
CSRF Token 失效AJAX 未攜帶 tokenYii 自動處理,確保表單有 request->csrfTokenName, Yii::app()->request->csrfToken); ?>
文件上傳字段驗證失效AJAX 無法上傳文件文件字段僅服務端驗證,或使用 FormData + 獨立上傳接口
多表單頁面衝突form id 重複每個 CActiveForm 必須設置唯一 id

總結

Yii CActiveForm AJAX 驗證核心三步:視圖 enableAjaxValidation=true → 控制器攔截 $_POST['ajax'] → CActiveForm::validate() 返回 JSON。配合 enableClientValidation 實現客戶端即時反饋、服務端權威校驗的雙重保障。關鍵細節:表單 ID 唯一、驗證攔截優先於賦值、Yii::app()->end() 終止執行、CSRF 自動處理。掌握此模式,可構建媲美 SPA 體驗的傳統表單交互。

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