Пустые значения, переданные валидаторам Zend framework 2

как я могу передать пустое значение через Zend framework 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;
    }
    

5 ответов


следующие работы для 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

это довольно раздражает, когда у вас есть конкретные случаи, такие как проверка URL-адреса, назначенного странице в вашей CMS, и избежание конфликтов (пустой 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() {}
}

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

    // ...
}

это вызвало проверку моего Callback validator, когда значение было пустой строкой:

'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 позволяет затем оценивать его валидаторами, которые следуют.


Я часто вижу, как люди делают ошибку, используя allowEmpty в массивах конфигурации inputFilter. Строка должна быть написана с разделением подчеркивания, а не с верблюжьим регистром. Так что allow_empty совместимость:

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

значение поля с ключом "fieldName" должно присутствовать в данных, но его значение должно быть пустым.


Если вы хотите использовать отдельный класс проверки формы или нотацию массива для проверки, вы можете сделать следующее:

$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 для ввода фильтра фабрики (как я помню, вы можете передать его непосредственно на входной фильтр тоже-не так уверен).