gpt4 book ai didi

validation - ZF2 - 验证器链不在空元素上运行

转载 作者:行者123 更新时间:2023-12-02 22:15:57 25 4
gpt4 key购买 nike

我已经创建了一个自定义验证器,它需要填写“门牌号”或“固定号码”,但不能同时填写两者 (XOR)。

如果两个字段都已填写(失败),或者如果一个字段已填写(通过),则验证器工作正常。但如果两个字段都为空,则验证器根本不会运行。

这是两个元素的输入过滤器规范:

$input = new Input('flat_number');
$input->setRequired(true);
$input->setAllowEmpty(true);
$input->setValue($this->flatNumber);
$input->getValidatorChain()
->addValidator(new \Si\Validator\HouseFlatCheck('house_number'))
->addValidator(new \Zend\Validator\StringLength(array('max' => 30)));
$input->getFilterChain()->attach($this->defaultFilterChain);
$inputFilter->add($input);

$input = new Input('house_number');
$input->setRequired(true);
$input->setAllowEmpty(true);
$input->setValue($this->houseNumber);
$input->getValidatorChain()
->addValidator(new \Si\Validator\HouseFlatCheck('flat_number'))
->addValidator(new \Zend\Validator\StringLength(array('max' => 30)));
$input->getFilterChain()->attach($this->defaultFilterChain);
$inputFilter->add($input);

从表面上看,如果字段为空并通过“required”和“allowEmpty”要求,则验证器不会运行。

有什么方法可以让“HouseFlatCheck”验证程序针对我的两个元素运行,尽管两个字段都是空的?

最佳答案

经过一整天的调查,我找到了解决该问题的途径。

首先,Zend\InputFilter\BaseInputFilter 类包含以下 isValid():

public function isValid()
{
if (null === $this->data) {
throw new Exception\RuntimeException(sprintf(
'%s: no data present to validate!',
__METHOD__
));
}

$this->validInputs = array();
$this->invalidInputs = array();
$valid = true;

$inputs = $this->validationGroup ?: array_keys($this->inputs);
foreach ($inputs as $name) {
$input = $this->inputs[$name];
if (!array_key_exists($name, $this->data)
|| (null === $this->data[$name])
|| (is_string($this->data[$name]) && strlen($this->data[$name]) === 0)
) {
if ($input instanceof InputInterface) {
// - test if input is required
if (!$input->isRequired()) {
$this->validInputs[$name] = $input;
continue;
}
// - test if input allows empty
if ($input->allowEmpty()) {
$this->validInputs[$name] = $input;
continue;
}
}
// make sure we have a value (empty) for validation
$this->data[$name] = '';
}

if ($input instanceof InputFilterInterface) {
if (!$input->isValid()) {
$this->invalidInputs[$name] = $input;
$valid = false;
continue;
}
$this->validInputs[$name] = $input;
continue;
}
if ($input instanceof InputInterface) {
if (!$input->isValid($this->data)) {
// Validation failure
$this->invalidInputs[$name] = $input;
$valid = false;

if ($input->breakOnFailure()) {
return false;
}
continue;
}
$this->validInputs[$name] = $input;
continue;
}
}

return $valid;
}

由于我的 Input 的 allowEmpty 为真,因此该 Input 的验证停止并移至数组中的下一个 Input 元素。将我的 Input 上的 allowEmpty 更改为 false 可以解决该问题,但会产生另一个问题,因为 'Zend\InputFilter\Input' 类在其 isValid() 函数期间调用以下函数:

protected function injectNotEmptyValidator()
{
if ((!$this->isRequired() && $this->allowEmpty()) || $this->notEmptyValidator) {
return;
}
$chain = $this->getValidatorChain();

// Check if NotEmpty validator is already first in chain
$validators = $chain->getValidators();
if (isset($validators[0]['instance'])
&& $validators[0]['instance'] instanceof NotEmpty
) {
$this->notEmptyValidator = true;
return;
}

$chain->prependByName('NotEmpty', array(), true);
$this->notEmptyValidator = true;
}

因为我的字段是必需的并且 allowEmpty 现在是 false,所以“NotEmpty”验证器会自动添加到我的链中。一旦发现,解决方案就很简单了。我在我的自定义库中创建了一个“输入”类,它覆盖了 injectNotEmptyValidator 函数,迫使它什么都不做:

namespace Si\InputFilter;

class Input extends \Zend\InputFilter\Input {
protected function injectNotEmptyValidator() {
return;
}
}

执行上述操作意味着“NotEmpty”未添加到我的验证器链中,因此我的 XOR 验证器可以正确运行。我现在要做的就是使用我更正的 Si\InputFilter\Input 类为这两个元素填充 InputFilter。

希望对您有所帮助。

关于validation - ZF2 - 验证器链不在空元素上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14454927/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com