13

如何通过 Zend 框架 2 ValidatorChain 将空值传递给我的自定义验证器?

在 ZF1 上可以通过allowEmpty(false)

在具有空元素值的 ZF2 上:

  • 如果allowEmpty = false, NotEmptyValidator 被添加到 ValidatorChain 的顶部, breakOnFailure = true, @see Zend/InputFilter/Input#injectNotEmptyValidator

  • 如果allowEmpty = true,元素被认为是有效的,@see Zend/InputFilter/BaseInputFilter#isValid

    if ($input->allowEmpty()) {
        $this->validInputs[$name] = $input;
        continue;
    }
    
4

5 回答 5

26

continue_if_empty解决了我的问题。感谢@dson-horácio-junior。这是我使用的:

$this->add(array(
    'name' => 'field',
    'continue_if_empty' => true,
    'filters' => array(
        array('name' => 'StripTags'),
        array('name' => 'StringTrim')
    ),
    'validators' => array(
        array(
            'name' => 'Application\Form\Validator\Sample'
        )
    )
));

public function isValid($value, $context = null)
{
    if ($value == '' && $context['otherfield'] == '') {
        $this->error(self::INVALID_FIELD);

        return false;
    }

    // ...
}
于 2014-07-08T12:55:06.457 回答
14

以下适用于 ZF2 版本 2.1.1:

问题(如果我理解正确的话)是在下面的示例中,对于 的空值'fieldName',不会触发验证。这可能很烦人,尽管在

$input = new \Zend\InputFilter\Input('fieldName');

$input
    ->setAllowEmpty(true)
    ->setRequired(false)
    ->getValidatorChain()
    ->attach(new \Zend\Validator\Callback(function ($value) {
        echo 'called validator!';

        return true; // valid
    }));

$inputFilter = new \Zend\InputFilter\InputFilter();
$inputFilter->add($input);

$inputFilter->setData(array('fieldName' => 'value'));
var_dump($inputFilter->isValid()); // true, echoes 'called validator!'

$inputFilter->setData(array('fieldName' => ''));
var_dump($inputFilter->isValid()); // true, no output

$inputFilter->setData(array());
var_dump($inputFilter->isValid()); // true, no output

当您遇到特殊情况时,这很烦人,例如检查分配给 CMS 中页面的 URL 并避免冲突(空 URL 仍然是 URL!)。

有一种处理空字符串的方法,基本上是NotEmpty自己附加验证器,并避免调用setRequiredand setAllowEmpty。这基本上会告诉Zend\InputFilter\Input#injectNotEmptyValidator不要自己自动附加NotEmpty验证器:

$input = new \Zend\InputFilter\Input('fieldName');

$input
    ->getValidatorChain()
    ->attach(new \Zend\Validator\NotEmpty(\Zend\Validator\NotEmpty::NULL))
    ->attach(new \Zend\Validator\Callback(function ($value) {
        echo 'called validator!';

        return true; // valid
    }));

$inputFilter = new \Zend\InputFilter\InputFilter();
$inputFilter->add($input);

$inputFilter->setData(array('fieldName' => 'value'));
var_dump($inputFilter->isValid()); // true, echoes 'called validator!'

$inputFilter->setData(array('fieldName' => ''));
var_dump($inputFilter->isValid()); // true, echoes 'called validator!'

$inputFilter->setData(array());
var_dump($inputFilter->isValid()); // false (null was passed to the validator)

如果您还想检查null,则需要扩展Zend\InputFilter\Input如下:

class MyInput extends \Zend\InputFilter\Input
{
    // disabling auto-injection of the `NotEmpty` validator
    protected function injectNotEmptyValidator() {}
}
于 2013-02-16T21:47:16.017 回答
7

Callback当值为空字符串时,这触发了我的验证器的验证:

'required'          => false,
'allow_empty'       => false,
'continue_if_empty' => true,
'validators'        => array(
    array(
        'name'    => 'Callback',
        'options' => array(
            'callback' => function ($value, $context = []) use ($self) {
                // ...
            }
        )
    )
)

allow_empty最初使空字符串无效,然后continue_if_empty允许随后的验证器对其进行评估。

于 2014-11-07T18:43:10.393 回答
2

如果您喜欢使用单独的表单验证类或数组表示法进行验证,您可以执行以下操作:

$factory     = new Zend\InputFilter\Factory();
$inputFilter = new Zend\InputFilter\InputFilter();

$inputFilter->add($factory->createInput(array(
    'name' => 'name',
    'required' => false,
    'allowEmpty' => true,
    'filters' => array(
        array('name' => 'StripTags'),
        array('name' => 'StringTrim'),
    ),
    'validators' => array(
        array(
            'name' => 'StringLength',
            'options' => array(
                'encoding' => 'UTF-8',
                'min' => '8',
                'max' => '100',
            ),
        ),
    ),
)));

您可以将数组与required => false输入allowEmpty => true过滤器工厂一起传递(我记得您也可以将它直接传递给输入过滤器 - 不太确定)。

于 2014-02-26T09:35:58.090 回答
2

我经常看到人们allowEmpty在 inputFilter 配置数组中使用错误。字符串应该用下划线分隔而不是驼峰式书写。所以allow_empty会起作用:

'fieldName' => array(
    'name'        => 'fieldName',
    'required'    => true,
    'allow_empty' => true,
    'filters' => array(
        //... your filters ...
    )
    'validators' => array(
        //... your validators ...
    ),
);

这意味着数据中必须存在键为“fieldName”的字段,但其值允许为空。

于 2015-02-11T11:11:06.760 回答