实际工作中的yii2到底有哪些部分会与原生的不同?rules

2018-05-06  本文已影响0人  任我笑笑

rules

原生的写法

public function rules()
{
    return [
        // name, email, subject 和 body 属性必须有值
        [['name', 'email', 'subject', 'body'], 'required'],

        // email 属性必须是一个有效的电子邮箱地址
        ['email', 'email'],
    ];
}

实际当中,大概会有2处不同

1. 按项目写rules

可以暂时无视其中的UtilValidation,这是对rules的二次包装

    public function rules() {

        return [
          
            UtilValidation::required('id'),
            UtilValidation::length('id', 20, 20),
            UtilValidation::match('id', '半角英数字記号1'),
            
            UtilValidation::required('fileType'),
            UtilValidation::match('fileType', '/^[0-1]{1}$/'),
         
            UtilValidation::required('downloadResult'),
            UtilValidation::length('downloadResult', 1, 2),
            UtilValidation::match('downloadResult', '半角数字')
        ];
    }

2. 自定义check rules

class UtilValidation {
    static public function required($sName, $sMsg = CommonForm::ERR_REQUIRED, $aOn = array()) {

        return array($sName, 'required', 'message' => $sMsg, 'on' => $aOn);
    }
。。。。。
    static public function dateYmdNumOnly($sName, $sMsg = CommonForm::ERR_DATE_FORMAT, $aOn = array()) {

        return array($sName, 'dateYmdCheckNumOnly', 'params' => array('message' => $sMsg), 'on' => $aOn);
    }

在父类的form中重写这个这个方法,加入自定义

 public function createValidators() //重写model的这个方法
    {
        $validators = new ArrayObject;
        foreach ($this->rules() as $rule) {
            if ($rule instanceof Validator) {
                $validators->append($rule);
            } elseif (is_array($rule) && isset($rule[0], $rule[1])) { // attributes, validator type
                $rule = $this->setCustomPattern($rule);    //重点在增加了这个方法 原生的model里面的createValidators里没有这个
                $validator = Validator::createValidator($rule[1], $this, (array) $rule[0], array_slice($rule, 2));
                $validators->append($validator);
            } else {
                throw new InvalidConfigException('Invalid validation rule: a rule must specify both attribute names and validator type.');
            }
        }
        return $validators;
    }


 protected function setCustomPattern($aRule) {

        if(!isset($aRule['pattern'])) {
            return $aRule;
        }
        switch($aRule['pattern']){
        case '半角数字':
            // 『0123456789』
            $aRule['pattern'] = '/^[0-9]+$/';
            break;
        case '半角英字':
            // 『abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ』
            $aRule['pattern'] = '/^[a-zA-Z]+$/';
            break;
        case '半角英数字':
            // 『abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789』
            $aRule['pattern'] = '/^[a-zA-Z0-9]+$/';
            break;
        default:
        }

        return $aRule;
    }

    public function dateYmdCheckNumOnly($attribute, $params)
    {
        $dateTime = $this->$attribute;

        if ($dateTime !== date("Ymd", strtotime($dateTime))) {
            $this->addError($attribute, $params['message']);
            return;
        }
    }

简单来说 ,普通的常规方法,先用UtilValidation进行封装,然后用setCustomPattern来进行替换,不用替换的直接走方法譬如dateYmdCheckNumOnly

这么做的好处就是把一些通用的正则规整到一个地方,避免每人copy一次的尴尬

3. 对于error的处理不同

一般的理解来说,如果form的check有问题,一般是要返回出什么错误的
但是如果是restful的app,前端的check一般交给app去做了
后端只要form的check不过,返回同一个错误代码就可以了

        $oModel = new GetXXXForm();
        $oModel->load($oRequest->post());
        $bRet = $oModel->validate();
        if ($this->oModel->hasErrors() || $bRet === false) {
            Yii::$app->log4->writeLog('xxx');
            $this->doResponse(parent::RESULT_PARAMERR, null); //这里返回json就完事了
            

当然,在自己的log里,还是要区分这是什么错误,所以重写了afterValidate

  public function afterValidate() {

        $aErrorList = $this->getErrors();

        foreach ($aErrorList as $sAttribute => $aError) {
            foreach ($aError as $sError) {
                $sLogId = 'PM000001';
                switch ($sError) {
                    case CommonForm::ERR_REQUIRED:
                        $sLogId = 'PM000002';
                        break;
                    case CommonForm::ERR_LENGTH:
                        $sLogId = 'PM000006';
                        break;
.........
                    case CommonForm::ERR_NUMBER_TOO_SMALL:
                        $sLogId = 'PRM000003';
                        break;
                    default:
                        break;
                }
                Yii::$app->log4->writeLog($sLogId, array('param' => $sAttribute, 'value' => var_export($this->$sAttribute, true)));
            }
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读