2013-02-16 61 views
13

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

这是可能的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; 
    } 
    
+1

http://akrabat.com/zend-framework-2/setting-up-required-fields-that-c​​an-be-empty-with-zendinputfilter/ – Sam 2013-02-16 13:58:36

+0

这不是我需要的,因为如果allow_empty = true,我的元素值为空,zf2认为该元素是有效的,不会调用验证器。 – deyine 2013-02-16 14:29:03

+0

我想我不明白你的问题。要么你允许空值,要么你不允许。如果你不允许空值,那么所有的验证器都会运行,否则验证会失败,当一个空的输入被给出时。如果你确实允许,那么一个空值就不需要进一步确认了o0 – Sam 2013-02-16 15:29:43

回答

14

以下工作为2.1.1版本ZF2:

的问题(如果我没有得到它)​​是在例如,对于'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不utomatically附上了自己的一个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() {} 
} 
+0

你已经去了,我想检查空和空,所以你最后的解决方案确认我的实施。非常感谢。 – deyine 2013-02-16 23:48:07

+5

只要执行'$ input-> setContinueIfEmpty(true);'而不是扩展_Zend \ InputFilter \ Input_,它会产生相同的效果,减少工作量并且简化操作。 – 2013-11-19 11:21:00

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输入滤波器工厂(因为我记得你可以直接将它传递给输入滤波器 - 不太确定)。

25

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

    // ... 
} 
+0

完美的答案。谢谢 – Abadis 2015-02-05 07:28:10

+0

最佳答案!值得更多upvotes。如果您将'continue_if_empty'设置为'true',那么'InputFilter \ Factory'不会自动添加'NotEmpty'验证器,因此所有验证都会转到用户定义的验证器。 – kachar 2015-05-26 10:45:17

+0

很好的答案谢谢你+1 – 2016-04-25 10:27:44

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允许它然后是由后面的验证器进行评估。

+0

这是工作的解决方案,谢谢本 – 2016-04-15 11:55:57

+0

保存我的一天!谢谢 – 2017-02-23 04:12:59

2

我经常看到在inputFilter配置数组中使用allowEmpty来犯错误的人。字符串应该用下划线分隔,而不是与骆驼大小写。所以allow_empty将工作:

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

意思与关键“字段名”字段必须存在于数据,但其价值被允许为空。