Пустые значения, переданные в валидаторы 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;
}
Ответы
Ответ 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" должно присутствовать в данных, но его значение разрешено быть пустым.