Pragmatism in the real world

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.

Firstly, contine_if_empty controls if the validators are run for an empty value. If contine_if_empty is true, then the validators are always executed.

If contine_if_empty is false, then the decision on whether to run the validators depends on the combination of required and allow_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!

3 thoughts on “Zend\Input and empty values

Comments are closed.