Подтвердить что ты не робот

Пустые значения, переданные в валидаторы 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;
    }
    
4b9b3361

Ответ 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

Это довольно неприятно, когда у вас есть определенные случаи, например, проверка 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() {}
}

Ответ 2

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

    // ...
}

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

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