在 Yii 中處理表單遵循標準的 MVC 模式,主要包含三個步驟:
根據資料用途選擇模型類型:
CFormModel):資料僅供暫時使用、不需持久化CActiveRecord):資料需儲存至資料庫兩者共享基類 CModel,提供統一的表單介面。
class LoginForm extends CFormModel {
public $username;
public $password;
public $rememberMe = false;
private $_identity;
public function rules() {
return array(
array('username, password', 'required'), // 必填欄位
array('rememberMe', 'boolean'), // 布林值驗證
array('password', 'authenticate'), // 自訂驗證方法
);
}
public function authenticate($attribute, $params) {
$this->_identity = new UserIdentity($this->username, $this->password);
if (!$this->_identity->authenticate()) {
$this->addError('password', '錯誤的用戶名或密碼。');
}
}
}
Yii 內建豐富的驗證器別名,涵蓋常見業務需求:
| 別名 | 對應類別 | 用途 |
|---|---|---|
| required | CRequiredValidator | 必填驗證 |
| CEmailValidator | Email 格式 | |
| length | CStringValidator | 長度範圍 |
| compare | CCompareValidator | 欄位比較 |
| unique | CUniqueValidator | 唯一性檢查 |
| captcha | CCaptchaValidator | 驗證碼 |
| file | CFileValidator | 檔案上傳 |
| match | CRegularExpressionValidator | 正則表達式 |
| numerical | CNumberValidator | 數值格式 |
| url | CUrlValidator | URL 格式 |
| boolean | CBooleanValidator | 布林值 |
| exist | CExistValidator | 資料庫存在性 |
| default | CDefaultValueValidator | 預設值 |
| filter | CFilterValidator | 資料過濾 |
| in | CRangeValidator | 範圍值 |
| type | CTypeValidator | 資料型別 |
透過 scenario 機制控制不同情境下的驗證規則與可賦值屬性:
public function rules() {
return array(
array('username, password', 'required'), // 所有場景
array('password_repeat', 'required', 'on' => 'register'), // 僅註冊場景
array('password', 'compare', 'on' => 'register'), // 僅註冊場景
);
}
// 控制器中指定場景
$model = new User('register');
$model->attributes = $_POST['User']; // 僅賦值 register 場景允許的屬性
安全屬性原則:出現在當前場景驗證規則中的屬性視為安全,可進行大量賦值。若需標記無驗證規則但可賦值的屬性,使用 array('content', 'safe');反之以 unsafe 排除。
$model->attributes = $_POST['User'];
if ($model->validate()) {
// 驗證通過
} else {
$errors = $model->getErrors(); // 所有錯誤
$firstError = $model->getError(); // 首個錯誤
}
public function actionLogin() {
$model = new LoginForm;
if (isset($_POST['LoginForm'])) {
$model->attributes = $_POST['LoginForm'];
if ($model->validate()) {
$this->redirect(Yii::app()->user->returnUrl);
}
}
$this->render('login', array('model' => $model));
}
關鍵點:$model->attributes = $_POST['LoginForm'] 依賴表單欄位命名規範 ModelName[attribute](如 LoginForm[username])。
echo CHtml::activeLabel($model, 'username');
echo CHtml::activeTextField($model, 'username');
echo CHtml::activePasswordField($model, 'password');
echo CHtml::activeCheckBox($model, 'rememberMe');
echo CHtml::submitButton('登入');
$form = $this->beginWidget('CActiveForm');
echo $form->errorSummary($model);
echo $form->label($model, 'username');
echo $form->textField($model, 'username');
echo $form->label($model, 'password');
echo $form->passwordField($model, 'password');
echo $form->checkBox($model, 'rememberMe');
echo $form->label($model, 'rememberMe');
echo CHtml::submitButton('登入');
$this->endWidget();
CActiveForm 提供客戶端與伺服器端無縫整合的一致性驗證體驗。
適用於一次編輯多筆資料的場景(如後台商品列表編輯):
public function actionBatchUpdate() {
$items = $this->getItemsToUpdate();
if (isset($_POST['Item'])) {
$valid = true;
foreach ($items as $i => $item) {
if (isset($_POST['Item'][$i])) {
$item->attributes = $_POST['Item'][$i];
}
$valid = $valid && $item->validate();
}
if ($valid) { /* 儲存邏輯 */ }
}
$this->render('batchUpdate', array('items' => $items));
}
視圖中使用 [$i]attributeName 命名慣例:
foreach ($items as $i => $item) {
echo CHtml::activeTextField($item, "[$i]name");
echo CHtml::activeTextField($item, "[$i]price");
}
Yii 表單系統透過模型封裝驗證邏輯、控制器協調流程、視圖靈活渲染,構建出高度可維護的表單處理架構。善用場景機制與 CActiveForm,能顯著提升開發效率與使用者體驗。