控制器層 <?php namespace frontend\controllers; use Yii; use frontend\models\FormsModel; use yii\web\UploadedFile; class FormsController extends \yii\web\Controller { /** * 生成驗證碼的方法 */ public function actions() { parent::actions(); return [ 'captcha' => [ 'class' => 'yii\captcha\CaptchaAction', //'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, //'backColor'=>0x00ff00,//背景顏色 //'padding'=>5,//間距 //'height'=>40,//高度 //'width'=>150,//寬度 //'foreColor'=>0x000000,//字體顏色 //'offset'=>4,//設置字符偏移量 有效果 'maxLength' => 3, 'minLength' => 3 ], ]; } public function actionIndex() { $model = new FormsModel; if($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, ['username', 'email', 'phone']); } //上傳圖片 $model->userimg= UploadedFile::getInstance($model, 'userimg'); if($files = $model->upload()){ $post = Yii::$app->request->post(); //var_dump($post);die; $hobbys = $post['FormsModel']['hobby']; $model->hobby = implode(',',$hobbys); $model->userimg = $files; if($model->save(false)){ echo 'ok'; } else { echo '添加失敗'; } } else { //上傳失敗 print_r($model->errors); } } else { return $this->render('index',['model'=>$model]); } } } 驗證模型層 <?php namespace frontend\models; use Yii; use yii\captcha\Captcha; /** * This is the model class for table "forms". * * @property integer $id * @property string $username * @property string $password * @property integer $age * @property string $sex * @property string $phone * @property string $email * @property string $userimg * @property string $hobby */ class FormsModel extends \yii\db\ActiveRecord { public $captcha; public $repassword; /** * @inheritdoc */ public static function tableName() { return 'forms'; } /** * @inheritdoc */ public function rules() { return [ [['username', 'password', 'repassword', 'workyear', 'age', 'sex', 'phone','email','hobby','selfdesc'], 'required', 'message'=>'{attribute}不能爲空'], [['username', 'password', 'repassword', 'workyear', 'age', 'sex', 'phone','email','selfdesc'], 'filter', 'filter'=>'trim'], [['username'], 'match', 'pattern'=>'/^\w{6,20}$/', 'message'=>'{attribute}爲6-20位數字字母或下劃線'], //['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'], ['password','match','pattern'=>'/^[a-zA-z]\w{5,20}$/','message'=>"{attribute}6-20位數字字母下劃線組成,不能以數字開頭"], ['repassword','compare','compareAttribute'=>'password','message'=>"兩次密碼不一致"], ['age','number','integerOnly'=>true,'max'=>50,'min'=>18,"tooBig"=>"18-50之內的整數","tooSmall"=>'18-50之內的整數'], ['sex', 'in', 'range'=>['男', '女'], 'message'=>'{attribute}只能是男或女'], ['phone', 'match', 'pattern'=>'/^1[3,5,8]\d{9}$/','message'=>"{attribute}必須由13,15,18開頭且11位數字組成"], ['selfdesc','match','pattern'=>'/^[\x{4e00}-\x{9fa5}]{3,18}$/u','message'=>"{attribute}必須由3到18個漢字組成"], [['username','email','phone'],'unique','message'=>"{attribute}必須惟一"], //['phone', 'checkPhone'], ['email', 'email'], //['email', 'unique'], ['userimg', 'file', 'skipOnEmpty'=>false, 'extensions'=>'png,jpg,gif'], ['captcha', 'captcha', 'message'=>'請輸入正確地{attribute}','captchaAction'=>'forms/captcha'], ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id' => 'ID', 'username' => '用戶名', 'password' => '密碼', 'age' => '年齡', 'sex' => '性別', 'phone' => '電話', 'email' => '郵箱', 'userimg' => '圖片', 'hobby' => '愛好', 'repassword'=>'確認密碼', 'captcha'=>'驗證碼', 'workyear'=>'工做經驗', 'selfdesc'=>'自我描述', ]; } //上傳圖片 public function upload() { if ($this->validate()) { $this->userimg->saveAs('./upload/forms/' . $this->userimg->baseName . '.' . $this->userimg->extension); return $this->userimg->baseName . '.' . $this->userimg->extension; } else { return false; } } } 工做經驗模型層 <?php namespace frontend\models; use Yii; /** * This is the model class for table "workyear". * * @property integer $w_id * @property integer $workyear */ class WorkyearModel extends \yii\db\ActiveRecord { /** * @inheritdoc */ public static function tableName() { return 'workyear'; } /** * @inheritdoc */ public function rules() { return [ [['workyear'], 'string', 'max' => 50] ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'w_id' => 'W ID', 'workyear' => '工做經驗', ]; } } 視圖層 <?php use yii\helpers\Html; use yii\widgets\ActiveForm; use yii\captcha\Captcha; use frontend\models\WorkyearModel; /* @var $this yii\web\View */ /* @var $model frontend\models\FormsModel */ /* @var $form ActiveForm */ ?> <div class="forms-index"> <?php $form = ActiveForm::begin(['id'=>'sign-form', 'options'=>['action'=>'forms/index', 'method'=>'post', 'enctype'=>'multipart/form-data']]); ?> <?= $form->field($model, 'username',['enableAjaxValidation' => true])->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'password')->passwordInput(['maxlength' => true]) ?> <?= $form->field($model, 'repassword')->passwordInput(['maxlength' => true]) ?> <?= $form->field($model, 'sex')->radioList(['男'=>'男','女'=>'女']) ?> <?= $form->field($model, 'age')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'phone',['enableAjaxValidation' => true])->textInput(['maxlength' => true]) ?> <?= $form->field($model,'workyear')->dropdownList(WorkyearModel::find()->select(['workyear', 'w_id'])-> indexBy('w_id')->column(),['prompt'=>'請選擇工做經驗']);?> <?= $form->field($model, 'email',['enableAjaxValidation' => true]) ?> <?= $form->field($model, 'hobby')->checkboxList(['唱歌'=>'唱歌','跳舞'=>'跳舞','看電影'=>'看電影']) ?> <?= $form->field($model, 'selfdesc')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'userimg')->fileInput() ?> <?= $form->field($model, 'captcha')->widget(Captcha::className(), ['captchaAction'=>'forms/captcha', 'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>', ]) ?> <div class="form-group"> <?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?> </div> <?php ActiveForm::end(); ?> </div><!-- forms-index --> 解析: Filter: 過濾,'filter'=>'trim',表示去空格 Required:必須的,表示不能爲空 Match: 匹配正則,須要和pattern一塊兒使用,定義正則表達式,'pattern'=>'/^\w{6,20}$/', Unique:驗證數據惟一性,在註冊時用到的比較多,這裏須要注意的是,在rules規則裏面定義的惟一性驗證,只有在服務器端才能驗證,若是想要在表單頁面顯示,須要開啓」enableAjaxValidation」=>ture; 例如: <?php $form = ActiveForm::begin([ 'id'=>'sign-form', //'enableAjaxValidation' => true,//啓用ajax驗證,將屬性值發送到服務器端進行驗證並返回結果,默認爲false 'enableClientValidation' => true,//啓用客戶端驗證,默認值爲true,關閉後表單無js驗證 'options'=>['action'=>'usermessage/signform', 'method'=>'post', 'enctype'=>'multipart/form-data']]); ?> 這裏須要注意的是,在這裏啓用的話,ajax驗證是做用於全部的屬性的,因此,還有另外一種開啓方式,在某一個field裏面開啓:<?= $form->field($model, 'username', ['enableAjaxValidation'=>true])->textInput() ?>,這樣就單獨做用於username屬性了。 要想實現表單ajax驗證惟一性,後臺還要一個ajax判斷: $model->load(Yii::$app->request->post()); if (Yii::$app->request->isAjax) { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; return \yii\bootstrap\ActiveForm::validate($model); } 在有數據提交時,最好先執行$model->load(Yii::$app->request->post()); 操做,不要作多餘的處理,而後判斷ajax,不然ajax驗證的時候可能會報錯500。若是有驗證碼, 這裏就會有另外一個問題:return \yii\bootstrap\ActiveForm::validate($model);這個驗證的是全部的屬性,而驗證碼執行validate後就會從新生成,那麼在表單提交時咱們進行數據有效性驗證時就會報錯, 解決方式:\yii\bootstrap\ActiveForm::validate()這個方法實際上是有兩個參數的,$model,$attributes,咱們能夠指定ajax驗證某一些特定的屬性,寫法是:\yii\bootstrap\ActiveForm::validate($model, ['username', 'email', 'phone']); 這樣ajax驗證時就只驗證username,email,phone這三個字段了,不會影響驗證碼。 Number:數字驗證,加上'integerOnly'=>true,表示只能是整數,max,min分別表示最大最小值,tooBig和tooSmall分別是超過最大值和低於最小值時的錯誤提示信息 Compare:比較,用於兩個屬性之間的比較,'compareAttribute'=>'password',表示與password比較 In:和range連用,定義範圍,表示屬性值必須在這個範圍內,一般用於驗證某些固定值 Email:郵箱驗證 File:文件驗證 extensions能夠定義上傳文件的類型 Captcha:驗證碼驗證,須要定義生成驗證碼的方法,'captchaAction'=>'usermessage/captcha',usermessage表示控制器名,captcha表示方法名 能夠在控制器層定義一個actions方法添加captcha方法: /** * 生成驗證碼的方法 */ public function actions() { parent::actions(); return [ 'captcha' => [ 'class' => 'yii\captcha\CaptchaAction', //'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, 'maxLength' => 3, 'minLength' => 3 ], ]; } 每個驗證均可以添加應用場景:’on’=>’register’; 在控制器層實例化模型層 $model = new Usermessage(); $model->setScenario('register'); 定義使用應用場景爲register 在模型層須要定義場景做用的對象 /** * 定義驗證場景 */ public function scenarios() { return [ 'register' => ['username', 'password', 'repassword', 'age', 'sex', 'phone','email'], 'login' => ['username', 'password','age', 'sex', 'phone','email'], ]; } 而後在對應的驗證規則後面限定應用場景’on’=>’register’; 當表單驗證時,爲在做用場景之內的參數能夠不受驗證規則的限制 添加入庫:複選框因提交過來後是一個數組,因此在執行save()前須要將複選框的值處理成字符串