Zend Framework 2, отфильтруйте значение после проверки в InputFilter

В InputFilter у меня есть этот код:

    $password = new Input('password');
    $password->setRequired(false)
             ->getValidatorChain()
             ->attach(new Validator\StringLength(6));

    $password->getFilterChain()
             ->attach($this->passwordHash);

Проблема в том, что фильтр применяется к значению до проверки, поэтому валидатор всегда возвращает true.

Мне было интересно, есть ли способ сделать фильтрацию после проверки.


person Rezouce    schedule 16.04.2014    source источник


Ответы (2)


Zend\InputFilter\FileInput — это один из типов ввода, который выполняет проверка перед фильтрацией. Вы можете увидеть, как они решили это в исходном коде, и создать свой собственный класс PasswordInput на основе этого решения.

Как вы можете видеть в исходном коде в строке 64 существует условие if, которое запрещает запуск фильтров, пока isValid равно false (начальное значение). Таким образом, сначала запускаются валидаторы, а затем, когда родитель InputFilter после проверки снова вызывает getValue, чтобы получить значение из FileInput, он запускает фильтры.

person Wilt    schedule 17.03.2015

Кажется странным фильтровать после проверки, поскольку входные данные до проверки могут быть отредактированы фильтрами. Например, стричь теги или обрезать строку. Если вы используете такой фильтр, как \Zend\I18n\Filter\Alnum(), вы можете позволить ему удалить пробелы. Поэтому рассматривайте это как плохую практику фильтрации после проверки вашего ввода.

Например, возьмите эти фильтры:

// Default settings, deny whitespace
$filter = new \Zend\I18n\Filter\Alnum();
echo $filter->filter("This is (my) content: 123");
// Returns "Thisismycontent123"

// First param in constructor is $allowWhiteSpace
$filter = new \Zend\I18n\Filter\Alnum(true);
echo $filter->filter("This is (my) content: 123");
// Returns "This is my content 123"

Обратите внимание, что начальное значение отличается от результата. Но вы можете фильтровать после проверки, но я думаю, вам придется это сделать самостоятельно. Таким образом, вы можете добавить метод в свой входной фильтр или форму, которую вы вызываете после проверки. Например:

public function filterPassword() {
    $filter = new \Zend\I18n\Filter\Alnum(true);
    $inputs = $this->getInputs();
    $password = $filter->filter($inputs['password']);
    return $password;
}

В вашем контроллере вы можете сделать это, например:

public function ExampleController extends AbstractActionController
{
    public function sampleAction() {
        $form = new LoginForm();
        if($form->isValid()) {
            $inputFilter = $form->getInputFilter();
            $filterdPassword = $inputFilter->filterPassword();
        }
        return array('form' => $form);
    }
}
person Kwido    schedule 24.07.2014
comment
Что делать, если фильтр нужен для того, чтобы загрузить файл в облако, но перед ним должны быть выполнены все проверки? - person Alexey Kosov; 02.09.2015
comment
@AlexeyKosov, фильтры и проверки должны выполняться перед сохранением любых данных, будь то модель или загрузка. И я понятия не имею, что вы имеете в виду: фильтр нужен для загрузки. Можете ли вы объяснить это немного подробнее? Насколько я могу судить, вы не используете фильтр для загрузки, а только для изменения имени файла или шифрования или расшифровки. PS: OP запрашивает способ фильтрации после его проверки, и я предоставил ему подход, поэтому я не понимаю, почему ваш комментарий связан. Другой ответ говорит о fileInputs, и я не отвечаю на это. - person Kwido; 08.09.2015