【问题标题】:use "when" in nested yii2 EachValidator在嵌套的 yii2 EachValidator 中使用“when”
【发布时间】:2019-02-20 19:54:58
【问题描述】:

有没有办法在嵌套的 EachValidator 中使用 when 属性? 这是我的规则,但它不起作用:

[['list'], 'each', 'rule' => ['required', 'when' => function ($model) {return false;}, 'whenClient' => "function (attribute, value) {return false;}"]],

我想测试是否可以在某些情况下避免所需的验证。 所以为了测试它,我总是说return false。 它只是一个测试返回语句,以验证它是否有效。

【问题讨论】:

  • 你能否解释一下你实际上想要做什么,你说什么我想测试一下我是否可以避免对某些要求的验证条件。 但这并没有定义实际问题,可能是解决问题的方法应该与当前不同。

标签: php yii2 yii2-validation


【解决方案1】:

如果您查看 yii\validators\EachValidator 源代码,rule 内部验证器中的 when 属性从未被调用:

if (!$validator->skipOnEmpty || !$validator->isEmpty($v)) {
    $validator->validateAttribute($model, $attribute);
}

比较它的父类yii\validators\Validator,它有这个:

foreach ($attributes as $attribute) {
    $skip = $this->skipOnError && $model->hasErrors($attribute)
        || $this->skipOnEmpty && $this->isEmpty($model->$attribute);
    if (!$skip) {
        if ($this->when === null || call_user_func($this->when, $model, $attribute)) {
            $this->validateAttribute($model, $attribute);
        }
    }
}

实现目标的一种方法是扩展 yii\validators\EachValidator 并覆盖其 validateAttribute($model, $attribute) 方法(以及其中定义的私有属性和方法):

/**
 * @var Validator validator instance.
 */
private $_validator;

/**
 * Returns the validator declared in [[rule]].
 * @param Model|null $model model in which context validator should be created.
 * @return Validator the declared validator.
 */
private function getValidator($model = null)
{
    // same as in parent
}

/**
 * Creates validator object based on the validation rule specified in [[rule]].
 * @param Model|null $model model in which context validator should be created.
 * @throws \yii\base\InvalidConfigException
 * @return Validator validator instance
 */
private function createEmbeddedValidator($model)
{
    // same as in parent
}

/**
 * {@inheritdoc}
 */
public function validateAttribute($model, $attribute)
{
    ... // same as in parent
    foreach ($value as $k => $v) {
        $model->clearErrors($attribute);
        $model->$attribute = $v;
        // start override original code
        $skip = $validator->skipOnEmpty && $validator->isEmpty($v);
        if (!$skip) {
            if ($validator->when === null || call_user_func($validator->when, $model, $attribute)) {
                $validator->validateAttribute($model, $attribute);
            }
        }
        // end override original code
        $filteredValue[$k] = $model->$attribute;
        if ($model->hasErrors($attribute)) {
            ... // same as in parent
        }
    }
    ... // same as in parent
}

rules() 中使用您的自定义类,如下所示:

[['list'], \app\models\EachValidator::className(), 'rule' => ['required', 'when' => function ($model) {return false;}]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多