表单验证:链中只有一个验证器应该检查空/null值,其他验证器不应该检查


Form validation: only one validator of the chain should check against empty/null values, the rest of the validators should not

我有这个id_role输入,它根据另一个输入internet_access的值进行验证。id_role的验证器链有一个回调验证器,必须检查空/null值,该链中的其他验证器只能检查填充值。

我已经通过$id_role->setContinueIfEmpty(true)实现了对空/null值的检查,但这适用于链中的每个验证器。我需要它只应用于链的回调验证器。

这是实际的id_role输入:

$id_role = new Input('id_role');
$id_role->setContinueIfEmpty(true); //this allows to check against empty/null values
$id_role->getFilterChain()
        ->attach($FilterInt);
$id_role->getValidatorChain()
        ->attach(new Validator'Callback(function($value, $context=array()){
            return isset($context['internet_access']) && $context['internet_access'] == 1 && $value === 0 ? false : true;
        }))
        ->attach(new Validator'Db'RecordExists(...);

所以我的问题是回调验证器工作得很好,但它在DbRecordExists上失败了,因为它试图找到一个空的记录。DbRecordExists必须仅在实际填充了id_role时才尝试查找记录。

有没有一种方法可以以优雅的方式(在输入过滤器和/或输入中)做我想要的事情?

ValidatorChain::attach方法的第二个参数为$breakChainOnFailure,默认值为false。

在以下位置签出文档http://framework.zend.com/manual/2.2/en/modules/zend.validator.validator-chains.html

您应该将代码修改为:

$id_role->getValidatorChain()
    ->attach(
        new Validator'Callback(
            function($value, $context=array()){
                return isset($context['internet_access']) && $context['internet_access'] == 1 && $value === 0 ? false : true;
            }
        ),
        true //$breakChainOnFailure
    )
    ->attach(new Validator'Db'RecordExists(....));

我认为没有办法只在链的特定验证器中检查空/null值,因为当我执行$id_role->setContinueIfEmpty(true)时,它会影响整个验证器链,而不仅仅是一个特定的验证器,这是正确的行为。

因此,为了完成我所需要的,我必须将DbRecordExists Validator放入回调验证器中,并仅在值不为空/null时手动验证它:

$id_role = new Input('id_role');
$id_role->setContinueIfEmpty(true);
$id_role->getFilterChain()
        ->attach($FilterInt);
$id_role->getValidatorChain()
        ->attach(new Validator'Callback(function($value, $context=array()){
            if (isset($context['internet_access']) && $context['internet_access'] == 1 && $value === 0) {
                return false;
            }
            if ($value !== 0) {
                $dbRecordExists = new Validator'Db'RecordExists(...);
                if (!$dbRecordExists->isValid($value)) {
                    return false;   
                }
            }
            return true;
        }));

我不知道这是否是最好的解决方案,但它确实奏效了。我希望这能对其他有同样问题的人有所帮助。