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.