Over a million developers have joined DZone.

Zend\Input Fallback Value

A regression was discovered in the Zend Framework Zend\InputFilter where the fallback value wasn't being populated correctly. This is a review of the fix.

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

Recently an issue was reported against Zend\InputFilter where the fallback value wasn't being populated correctly. Matthew investigated, fixed it and asked me to review it.

I was fascinated as I didn't realise (or had completely forgotten!) that Zend\Input and Zend\InputFilter supported fallback values so I looked into it and it turns out that it's simple and works exactly as its name implies.

For the basic case of using an Input directly, you use it like this:

<?php
$name = new \Zend\InputFilter\Input('name');
$validators = $name->getValidatorChain();
$validators->addValidator(new \Zend\Validator\StringLength(5), true);

$name->setFallbackValue('Rob Allen');
$name->setValue('');

$isValid = $name->isValid();
var_dump($name->getValue());

The output is "Rob Allen".

That is, when the value supplied is empty, then, the fallback value is set instead and used.

A Wrinkle

There is, however, a wrinkle! Sometimes $name->getValue() returns an empty string and this occurs due to particular combinations of required, allow_empty & continue_if_empty as I've already discussed.

If continue_if_empty is false then the combination of required & allow_empty affects whether you get the fallback value or an empty string when calling getValue() after isValid():

required allow_empty What happens
true false With an empty value, the fallback value is returned in getValue().
true true The fallback value is ignored and an empty value is returned in getValue().
false false The fallback value is ignored and an empty value is returned in getValue().
false true The fallback value is ignored and an empty value is returned in getValue().

If you compare this table to the one in the last post, you'll notice that in the three cases where the validators are not run, the fallback value is not set. This is not surprising as those combinations result in a short-circuit of isValid().

Test App

Again, I used a test application to check this out

<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->setFallbackValue('Rob Allen');
    $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());
    } else {
        echo ", value = " . $name->getValue();
    }
    echo "\n";
}

As before, this app simply runs through all combinations of required, allow_empty & continue_if_empty against a Zend\InputFilter\Input with a fallback value set and sees what happens.

This is the output:

$ php test.php 
continue_if_empty: 0, required: 1, allow_empty: 0 - Result: isValid() = 1, value = Rob Allen
continue_if_empty: 0, required: 1, allow_empty: 1 - Result: isValid() = 1, value = 
continue_if_empty: 0, required: 0, allow_empty: 0 - Result: isValid() = 1, value = 
continue_if_empty: 0, required: 0, allow_empty: 1 - Result: isValid() = 1, value = 
continue_if_empty: 1, required: 1, allow_empty: 0 - Result: isValid() = 1, value = Rob Allen
continue_if_empty: 1, required: 1, allow_empty: 1 - Result: isValid() = 1, value = Rob Allen
continue_if_empty: 1, required: 0, allow_empty: 0 - Result: isValid() = 1, value = Rob Allen
continue_if_empty: 1, required: 0, allow_empty: 1 - Result: isValid() = 1, value = Rob Allen\

Zend\InputFilter

Note that with the fix discussed at the start of this post, Zend\InputFilter works exactly the same as Zend\Input, as you'd expect. This fix was back ported to the 2.4 release too, so if you are using fallback values, ensure that you're using the latest 2.4 or 2.5 version.

Conclusion

If you want to use a fallback value with Zend\Input make sure that you set required to true and allow_empty to false. Fortunately this is the default, so that's probably what you're doing anyway!

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:
php ,zend framework

Published at DZone with permission of Rob Allen, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}