rules
原生的写法
public function rules()
{
return [
// name, email, subject 和 body 属性必须有值
[['name', 'email', 'subject', 'body'], 'required'],
// email 属性必须是一个有效的电子邮箱地址
['email', 'email'],
];
}
实际当中,大概会有2处不同
- 并不是同一个check rules的会被写成一行,而是按项目分
- 有很多自定义的check rules
- 对于error的处理不同
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)));
}
}
}
网友评论