Yii2 內建 ActiveForm 支援 AJAX 驗證,配合模型規則即可實現用戶名/郵箱即時唯一性檢查,無需手寫 JS 請求。
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model frontend\models\SignupForm */
$this->title = '註冊';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-signup">
<h1><?= Html::encode($this->title) ?></h1>
<p>請填寫以下欄位完成註冊:</p>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin([
'id' => 'form-signup',
'enableAjaxValidation' => true, // 關鍵:啟用 AJAX 驗證
'enableClientValidation' => true, // 客戶端驗證(規則支援時)
]); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'email') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= $form->field($model, 'password_compare')->passwordInput() ?>
<div class="form-group">
<?= Html::submitButton('註冊', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
public function actionSignup() {
$model = new SignupForm();
// 載入 POST 資料(AJAX 驗證時為部分欄位)
$model->load(Yii::$app->request->post());
// AJAX 驗證請求
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return \yii\bootstrap\ActiveForm::validate($model); // 自動驗證並返回 JSON 錯誤
}
// 正常表單提交
if ($model->load(Yii::$app->request->post())) {
if ($user = $model->signup()) {
if (Yii::$app->getUser()->login($user)) {
return $this->goHome();
}
}
}
return $this->render('signup', ['model' => $model]);
}
namespace frontend\models;
use common\models\User;
use yii\base\Model;
use Yii;
class SignupForm extends Model {
public $username;
public $email;
public $password;
public $password_compare;
public function rules() {
return [
// 用戶名
['username', 'filter', 'filter' => 'trim'],
['username', 'required'],
['username', 'unique', 'targetClass' => '\common\models\User', 'message' => '用戶名已存在。'],
['username', 'string', 'min' => 2, 'max' => 255],
// 郵箱
['email', 'filter', 'filter' => 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'unique', 'targetClass' => '\common\models\User', 'message' => '郵箱已存在。'],
// 密碼
[['password', 'password_compare'], 'required'],
[['password', 'password_compare'], 'string', 'min' => 6, 'max' => 16, 'message' => '{attribute} 必須為 6-16 位數字或字母'],
['password_compare', 'compare', 'compareAttribute' => 'password', 'message' => '兩次密碼不一致'],
];
}
public function signup() {
if ($this->validate()) {
$user = new User();
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
if ($user->save()) return $user;
}
return null;
}
}
enableAjaxValidation => true:ActiveForm 自動監聽輸入事件,對配置了 unique 等伺服器端驗證規則的欄位發送 AJAX 請求。unique 驗證器:指定 targetClass 為 User 模型,自動查詢資料庫檢查唯一性。isAjax:AJAX 驗證請求直接返回 JSON 格式驗證結果,不渲染視圖。ActiveForm::validate($model):靜態方法自動執行模型驗證並格式化錯誤訊息供前端顯示。enableClientValidation => true 針對 required、string、email、compare 等規則生成 JS 驗證碼,減少伺服器請求。若需獨立驗證端點(如註冊頁外的用戶名檢查 API):
public function actionCheckUsername() {
Yii::$app->response->format = Response::FORMAT_JSON;
$username = Yii::$app->request->post('username');
$exists = User::find()->where(['username' => $username])->exists();
return ['valid' => !$exists, 'message' => $exists ? '用戶名已存在' : ''];
}
前端調用:$.post('/site/check-username', {username: val}, function(res){...})
Yii2 ActiveForm + unique 驗證器 + 控制器 isAjax 分流,僅需少量配置即可實現專業級即時唯一性驗證,兼顧用戶體驗與伺服器效能。