A free and open-source book on ZF3 for beginners


7.10. Добавление правил валидации формы

Валидация формы - это процедура фильтрации и проверки данных, передаваемых серверу при отправке формы. Например, для нашей формы обратной связи мы хотим сделать следующие проверки:

22) Злоумышленники могут вставлять HTML-код в сообщение. Если вы откроете такой код в браузере, вы можете увидеть нежелательное содержимое. Чтобы этого избежать, нужно заменить HTML-теги в теме сообщения и тексте.

Требования выше называются правилами валидации. Эти правила могут быть разделены на две категории: фильтры и валидаторы.

Фильтры изменяют введенные пользователем данные, чтобы исправить возможные ошибки или обеспечить соответствие данных определенному формату. Фильтры, как правило, применяются первыми, а валидаторы - последними.

Валидаторы проверяют, допустимы ли данные. Если все введенные данные корректны, форма считается действительной, и данные могут безопасно использоваться уровнем бизнес-логики. Если какое-то поле недействительно, валидатор устанавливает флаг ошибки. В этом случае, форма, как правило, снова показывается пользователю, и тому предлагается исправить ошибки ввода и переслать форму на сервер.

Что произойдет, если я не добавлю правило валидации для определенного поля формы?

Если вы не добавите правило валидации, отправленное пользователем значение не будет проверено, тем самым оставив дыру в безопасности вашего сайта. Рекомендуется всегда добавлять правило валидации для каждого поля формы, заполняемого пользователем, а также добавлять столько проверок каждому полю, сколько нужно для поддержания безопасности сайта.

7.10.1. Фильтр входных данных (Input filter)

В ZF3 правила валидации хранятся с помощью класса InputFilter. Этот класс определяется в компоненте Zend\InputFilter. Фильтр входных данных - это контейнер для так называемых входов (inputs). Как правило, вы добавляете входы для каждого поля модели.

Входы могут состоять из фильтров и/или валидаторов и некоторой дополнительной информации. Например, в них может содержаться флаг, указывающий на то, обязательно ли это поле, или его значение может отсутствовать в HTTP-запросе.

Аналогично добавлению полей модели формы, существует два способа добавить входы в фильтр: либо через передачу экземпляра класса ввода в качестве аргумента его метода add(), либо через передачу описания в виде массива 23. В следующем разделе мы опишем второй способ (он более предпочтителен, так как требует меньшего количества кода).

23) Во втором случае (описание в виде массива) вход будет автоматически создан с помощью класса Zend\InputFilter\Factory.

7.10.2. Добавление входов в фильтр

Чтобы добавить вход в фильтр, используйте метод `add(), который принимает описание входа в виде массива следующим образом:

[
    'name'     => '<name>',
    'type'     => '<type>',
    'required' => <required>,
    'filters'  => [
        // Добавьте конфигурацию фильтров ...
    ],                
    'validators' => [
        // Добавьте конфигурацию валидаторов ...
    ]
]

Этот массив содержит следующие ключи:

Рисунок 7.16. Наследование классов входов Рисунок 7.16. Наследование классов входов

7.10.2.1. Настройка фильтра

Типичная конфигурация фильтра представлена ниже:

[
    'name' => '<filter_name>',  
    'priority' => <priority>,
    'options' => [
        // Здесь идут опции фильтра ...
    ]
],                    

Ключ name (строка 2) - это имя фильтра. Это может быть либо полностью определенное имя класса фильтра (например, StringTrim::class) либо псевдоним (например, StringTrim).

Опциональный ключ priority (строка 3) определяет приоритет в списке фильтров. Это должно быть число типа integer. Фильтры с наивысшем приоритетом будут применены первыми. По умолчанию присваивается константа FilterChain::DEFAULT_PRIORITY (со значением 1000).

Массив options (строка 4), индивидуальный для каждого фильтра, может содержать параметры для настройки.

7.10.2.2. Настройка валидатора

Типичная конфигурация валидатора представлена ниже:

[
    'name' => '<validator_name>',
    'break_chain_on_failure' => <flag>,
    'options' => [
        // Здесь идут опции валидатора ...
    ]
],                    

Ключ name (строка 2) - это имя валидатора. Это может быть либо полностью определенное имя класса валидатора (например, `EmailAddress::class) либо псевдоним (например, EmailAddress).

Опциональный ключ break_chain_on_failure (строка 3) определяет поведение в случае неудачной проверки. При значении true, последующие валидаторы в списке не будут выполняться; в противном случае каждый валидатор в списке будет выполняться вне зависимости от результата других валидаторов.

Массив options (строка 4), индивидуальный для каждого валидатора, может содержать параметры для настройки.

7.10.3. Создание фильтра входных данных для формы обратной связи

Теперь, когда у вас есть общее представление о том, как заполнять фильтр входных данных фильтрами и валидаторами для каждого поля формы, давайте дополним наш класс модели формы ContactForm. В фрагменте кода ниже мы добавим метод addInputFilter(), который определяет правила фильтрации/валидации, хранит их в фильтре входных данных и добавляет фильтр к модели формы:

<?php
// ...
use Zend\InputFilter\InputFilter;

class ContactForm extends Form
{
    public function __construct()
    {
        // ... вызовите этот метод для добавления правил валидации
        $this->addInputFilter();
    }
    
    // ...
    
    // Этот метод создает фильтр входных данных (используемый для фильтрации/валидации).
    private function addInputFilter() 
    {
        // Используем стандартный InputFilter формы
        $inputFilter = $this->getInputFilter();
        
        $inputFilter->add([
            'name'     => 'email',
            'required' => true,
            'filters'  => [
                ['name' => 'StringTrim'],                    
            ],                
            'validators' => [
                [
                    'name' => 'EmailAddress',
                    'options' => [
                        'allow' => \Zend\Validator\Hostname::ALLOW_DNS,
                        'useMxCheck' => false,                            
                    ], 
                ],
            ],
        ]);
        
        $inputFilter->add([
            'name'     => 'subject',
            'required' => true,
            'filters'  => [
                ['name' => 'StringTrim'],
                ['name' => 'StripTags'],
                ['name' => 'StripNewlines'],
            ],                
            'validators' => [
                [
                    'name' => 'StringLength',
                    'options' => [
                        'min' => 1,
                        'max' => 128
                    ],
                ],
            ],
        ]);
    
        $inputFilter->add([
            'name'     => 'body',
            'required' => true,
            'filters'  => [                    
                ['name' => 'StripTags'],
            ],                
            'validators' => [
                [
                    'name' => 'StringLength',
                    'options' => [
                        'min' => 1,
                        'max' => 4096
                    ],
                ],
            ],
        ]);                
    }  
}

В этом фрагменте первым делом мы объявляем псевдоним для класса Zend\InputFilter\InputFilter (строка 3).

В конструкторе модели формы (строка 10), мы вызываем метод addInputFilter(), который определяется в строках 16-76.

Задача метода addInputFilter() - добавить правила фильтрации/валидации (строки 21-75). Чтобы добавить правила фильтрации/валидации в фильтр, используется метод add() класса InputFilter, принимающий описание входа, который нужно создать, в виде массива.

Мы добавляем три входа (по одному для каждого поля нашей модели формы, кроме кнопки отправки формы):

На рисунке 7.17 представлено схематическое графическое представление созданного нами фильтра входных данных.

Рисунок 7.17. Фильтр входных данных для ContactForm Рисунок 7.17. Фильтр входных данных для ContactForm

Выше мы вкратце описали, как создавать фильтр входных данных для модели формы. За более детальной информацией об упомянутых выше (и других) фильтрах и валидаторах, а также за примерами их использования, обратитесь к главам Преобразование данных с помощью фильтров и Проверка входных данных с помощью валидаторов.


Top