【问题标题】:Empty values passed to Zend framework 2 validators传递给 Zend 框架 2 验证器的空值
【发布时间】:2013-02-01 08:33:26
【问题描述】:

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

allowEmpty(false)在 ZF1 上是可能的

在具有空元素值的 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;
    }
    

【问题讨论】:

  • 这不是我需要的,因为如果 allow_empty = true 并且我的元素值为空,zf2 认为该元素是有效的并且不会调用验证器。
  • 我想我不明白你的问题。要么允许空值,要么不允许。如果您不允许空值,则所有验证器都将运行,否则在给出空输入时验证将失败。如果您确实允许它们,则不需要进一步验证空值 oO
  • 好的,为了简化描述,我如何使用 zf2 在字段上应用自定义验证器,即使它是空的。
  • 简化不是要走的路。你想验证什么? "" 是空的 - 没有验证。这是一个空字符串,你到底想用这个来验证什么?它只是没有丝毫意义。你到底想做什么?

标签: php validation zend-framework2 input-filter


【解决方案1】:

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 验证器,并避免调用setRequiredsetAllowEmpty。这基本上会告诉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() {}
}

【讨论】:

  • 你去吧,我想检查空和空,所以你的最后一个解决方案确认了我的实现。非常感谢。
  • 只做$input->setContinueIfEmpty(true);,而不是扩展Zend\InputFilter\Input,效果一样,工作量更少,更简单。
  • NotEmpty::NULL - 这有帮助。对于那些将fogetInputFilterSpecification() 与数组一起使用的人,您需要以下结构:'validators' => [[ 'name' => NotEmpty::class, 'options' => [ 'type' => NotEmpty::NULL ]]]'
【解决方案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 => falseallowEmpty => true 的数组传递给输入过滤器工厂(我记得您也可以将它直接传递给输入过滤器 - 不太确定)。

【讨论】:

    【解决方案3】:

    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;
        }
    
        // ...
    }
    

    【讨论】:

    • 完美答案。谢谢
    • 最佳答案!值得更多的支持。如果将continue_if_empty 设置为true,则InputFilter\Factory 不会自动添加NotEmpty 验证器,因此所有验证都将转到用户定义的验证器。
    • 我花了 30 分钟才找到这个选项非常感谢
    【解决方案4】:

    当值为空字符串时,这会触发我的 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 允许随后的验证器对其进行评估。

    【讨论】:

    • 拯救了我的一天!谢谢
    【解决方案5】:

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

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

    表示数据中必须存在键为“fieldName”的字段,但其值允许为空。

    【讨论】:

      猜你喜欢
      • 2021-07-23
      • 2017-05-06
      • 1970-01-01
      • 2012-07-26
      • 1970-01-01
      • 1970-01-01
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多