rules中定义的规则如下:
public function rules() { return [ ['price', 'required'], ['price', 'double'], ['price', function ($attr) { return $this->$attr > 0; }], ]; }
传入一个负数的价格,通过model的validate()方法进行校验时,始终能通过校验。最后通过查看Yii2的源代码,发现调用了下面这个方法:
\yii\validators\InlineValidator::validateAttribute
/**
* @inheritdoc
*/
public function validateAttribute($model, $attribute)
{
$method = $this->method;
if (is_string($method)) {
$method = [$model, $method];
}
call_user_func($method, $attribute, $this->params);//没有接收返回结果进行处理
}
而这个方法是重写了\yii\validators\Validator::validateAttribute方法的
/**
* Validates a single attribute.
* Child classes must implement this method to provide the actual validation logic.
* @param \yii\base\Model $model the data model to be validated
* @param string $attribute the name of the attribute to be validated.
*/
public function validateAttribute($model, $attribute)
{
$result = $this->validateValue($model->$attribute);
if (!empty($result)) {
$this->addError($model, $attribute, $result[0], $result[1]);
}
}
未重写前的方法,会接收返回结果进行判断,并将错误加入到\yii\base\Model::$_errors这个数组中进行记录,最后在\yii\base\Model::validate中判断是否有错误信息。
而\yii\validators\InlineValidator::validateAttribute这个重写后的方法并没有接收返回值,没有将错误信息进行记录。
所以,最上面的验证规则就失效了。
最终解决方案如下:在rules中手动添加错误信息成功解决
public function rules()
{
return [
['price', 'required'],
['price', 'double'],
['price', function ($attr) {
if ($this->$attr <= 0) {
$this->addError($attr, '价格必须大于0!');
}
}],
];
}