如何通过Zend framework 2 ValidatorChain将空值传递给我的自定义验证器?
可以通过allowEmpty(false)
在具有空元素值的ZF2上:
如果allowEmpty = false
,NotEmptyValidator将breakOnFailure = true
添加到ValidatorChain的顶部,@see Zend/InputFilter/Input#injectNotEmptyValidator
。
如果allowEmpty = true
,则元素被视为有效,@see Zend/InputFilter/BaseInputFilter#isValid
if ($input->allowEmpty()) {
$this->validInputs[$name] = $input;
continue;
}
答案 0 :(得分: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;
}
// ...
}
答案 1 :(得分: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
验证器,并避免调用setRequired
和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() {}
}
答案 2 :(得分: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
允许后面的验证器对其进行评估。
答案 3 :(得分: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
的数组传递给输入过滤器工厂(我记得您也可以直接将其传递给输入过滤器 - 不太确定)。
答案 4 :(得分:2)
我经常看到人们在inputFilter配置数组中使用allowEmpty
犯了错误。该字符串应使用下划线分隔,而不是使用camel case。所以allow_empty
会起作用:
'fieldName' => array(
'name' => 'fieldName',
'required' => true,
'allow_empty' => true,
'filters' => array(
//... your filters ...
)
'validators' => array(
//... your validators ...
),
);
意味着数据中必须存在键'fieldName'的字段,但其值必须为空。