Как я могу передать пустое значение через Zend framework 2 ValidatorChain в мой пользовательский валидатор?
Это возможно на ZF1 с помощью allowEmpty(false)
На ZF2 с пустым значением элемента:
Если allowEmpty = false
, NotEmptyValidator добавляется в начало ValidatorChain с breakOnFailure = true
, @see Zend/InputFilter/Input#injectNotEmptyValidator
.
Если allowEmpty = true
, элемент считается Valid, @see Zend/InputFilter/BaseInputFilter#isValid
if ($input->allowEmpty()) { $this->validInputs[$name] = $input; continue; }
Следующие работы для 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
что 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
когда значение было пустой строкой:
'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
в массивах configFilter. Строка должна быть написана с подчеркиванием подчеркивания не с верблюжьим футляром. Так 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
для ввода фабрики фильтров (поскольку я помню, вы можете передать его непосредственно на входной фильтр тоже – не так уверен).