Zend\Input and empty values
I’m forever getting confused about how the combination of Zend\Input‘s required, allow_empty & continue_if_empty interact with an empty value, so I’ve decided to write it down.
These settings define what happens when you try to validate an empty value for a given input. For Zend\Input, empty means exactly equal to null, an empty string or an empty array.
Firstly, let’s start with the three settings:
Setting | Default | What it does |
---|---|---|
required | true | When true, the value must not be empty (unless allow_empty is true). |
allow_empty | false | When true, the field may be empty if it’s required. |
continue_if_empty | false | When true, the validators are run even if the field is empty. |
required | allow_empty | What happens |
---|---|---|
true | false | For an empty value, the validators are run. isValid() is determined by the validators and is false as the NotEmpty validator fails. (This is the default) |
true | true | For an empty value, the validators are not run. isValid() = true. |
false | false | For an empty value, the validators are not run. isValid() = true. |
false | true | For an empty value, the validators are not run. isValid() = true. |
Test app
To prove this, I wrote this little test app:
?php require 'vendor/autoload.php'; $values = [ // [contine_if_empty, required, allow_empty] [false, true, false], [false, true, true], [false, false, false], [false, false, true], [true, true, false], [true, true, true], [true, false, false], [true, false, true], ]; foreach ($values as $row) { test(...$row); } function test($continueIfEmpty, $required, $allowEmpty) { // set up Input with a StringLength validator so we'll know if the // validators have run as they will always fail $name = new \Zend\InputFilter\Input('name'); $validators = $name->getValidatorChain(); $validators->addValidator(new \Zend\Validator\StringLength(5), true); $name->setValue(''); $name->setRequired($required); $name->setAllowEmpty($allowEmpty); $name->setContinueIfEmpty($continueIfEmpty); // Test echo "continue_if_empty: " . (int)$continueIfEmpty; echo ", required: " . (int)$required; echo ", allow_empty: " . (int)$allowEmpty; $isValid = (int)$name->isValid(); echo " - Result: isValid() = $isValid"; if (!$isValid) { echo " " . current($name->getMessages()); } echo "\n"; }
You’ll need to run composer require zendframework/zend-inputfilter if you want to test it yourself.
Interesting side note: I got to use the splat operator, so this is PHP 5.6 only code :)
The test is quite simple. We add a StringLength validator to an input so that we know that the validators have run as it will always fail. We then iterate through all the the combinations of required, allow_empty & continue_if_empty and see what happens.
The output is:
$ php test.php continue_if_empty: 0, required: 1, allow_empty: 0 - Result: isValid() = 0 Value is required and can't be empty continue_if_empty: 0, required: 1, allow_empty: 1 - Result: isValid() = 1 continue_if_empty: 0, required: 0, allow_empty: 0 - Result: isValid() = 1 continue_if_empty: 0, required: 0, allow_empty: 1 - Result: isValid() = 1 continue_if_empty: 1, required: 1, allow_empty: 0 - Result: isValid() = 0 The input is less than 5 characters long continue_if_empty: 1, required: 1, allow_empty: 1 - Result: isValid() = 0 The input is less than 5 characters long continue_if_empty: 1, required: 0, allow_empty: 0 - Result: isValid() = 0 The input is less than 5 characters long continue_if_empty: 1, required: 0, allow_empty: 1 - Result: isValid() = 0 The input is less than 5 characters long
Conclusion
The interactions between required, allow_empty & continue_if_empty aren’t that complicated, but there’s enough complexity that it’s worth having a reference handy!
Either you allow empty values or you don t. If you don t allow empty values, all validators will run, otherwise validation will fail, when an empty input is given.