Статьи

Zend \ Input Fallback Value

Недавно сообщалось о проблеме с Zend \ InputFilter, где запасное значение не заполнялось правильно. Мэтью исследовал, исправил это и попросил, чтобы я рассмотрел это.

Я был очарован, поскольку не осознавал (или совсем забыл!), Что Zend \ Input и Zend \ InputFilter поддерживают запасные значения, поэтому я посмотрел на него, и оказалось, что он прост и работает именно так, как следует из его названия.

Для базового случая непосредственного использования Input вы используете его следующим образом:

<?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());

То есть, когда предоставленное значение пустое, вместо этого устанавливается запасное значение и используется.

Морщина

Существует, однако, морщина! Иногда $ name-> getValue () возвращает пустую строку, и это происходит из-за определенных комбинаций required, allow_empty & continue_if_empty, как я уже обсуждал .

Если continue_if_empty имеет значение false, то комбинация обязательных & allow_empty влияет на то, получаете ли вы запасное значение или пустую строку при вызове getValue () после isValid ():

обязательный allow_empty Что происходит
правда ложный При пустом значении запасное значение возвращается в getValue ().
правда правда Резервное значение игнорируется, и в getValue () возвращается пустое значение.
ложный ложный Резервное значение игнорируется, и в getValue () возвращается пустое значение.
ложный правда Резервное значение игнорируется, и в getValue () возвращается пустое значение.

Если вы сравните эту таблицу с таблицей в последнем сообщении , вы заметите, что в трех случаях, когда валидаторы не запускаются, запасное значение не устанавливается. Это не удивительно, так как эти комбинации приводят к короткому замыканию isValid ().

Тестовое приложение

Опять же, я использовал тестовое приложение, чтобы проверить это

<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";
}

Как и прежде, это приложение просто запускает все комбинации обязательных allow_empty & continue_if_empty с Zend \ InputFilter \ Input с установленным запасным значением и видит, что происходит.

Это вывод:

$ 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

Обратите внимание, что с исправлением, обсужденным в начале этого поста, Zend \ InputFilter работает точно так же, как Zend \ Input, как и следовало ожидать. Это исправление было перенесено в версию 2.4, поэтому, если вы используете запасные значения, убедитесь, что вы используете последнюю версию 2.4 или 2.5.

Вывод

Если вы хотите использовать запасное значение с Zend \ Input, убедитесь, что вы установили значение required равным true, а allow_empty — false. К счастью, это по умолчанию, так что это, вероятно, то, что вы делаете в любом случае!