yii2 數據驗證

		


				控制器層

<?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()前須要將複選框的值處理成字符串

相關文章
相關標籤/搜索