A free and open-source book on ZF3 for beginners


9.4. Инстанцирование валидатора

В Zend Framework 3 существует несколько способов создания валидатора:

Далее мы рассмотрим эти три способа более детально.

9.4.1. Способ 1: Инстанцирование валидатора вручную

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

В качестве образца рассмотрим использование валидатора EmailAddress, который проверяет адрес электронной почты на соответствие стандарту RFC-2822. Электронный адрес, как правило, состоит из локальной части (имени пользователя), за которой следует символ "at" (@), также называемый "собакой", за которым в свою очередь следует имя хоста. Например, в адресе "name@example.com", "name" - локальная часть, а "example.com" - имя хоста.

Валидатор EmailAddress полезен для проверки введенных пользователями на формах электронных адресов на корректность. Валидатор будет проверять адрес на корректность локальной части и имени хоста, наличие символа "at" (@), а также (опционально) будет подключаться к хосту получателя и спрашивать DNS-сервер о существовании MX-записи (MX расшифровывается как Mail eXchanger - «почтовый обменник») 30.

30) MX-запись - это тип записи, используемый в системе доменных имен (Domain Name System - DNS). MX-записи определяют один или несколько адресов почтовых серверов, принимающих почту для домена получателя.

Методы, предоставляемые валидатором EmailAddress перечислены в таблице 9.2:

Table 9.2. Public-методы валидатора EmailAddress
Имя метода Описание
__construct($options) Конструктор валидатора. Принимает список опций для его настройки.
isValid($value) Вовращает true, если значение является действительным адресом эл. почты согласно RFC-2822; иначе возвращает false.
getMessages() Если валидация была неудачной, этот метод вернет массив сообщений об ошибках.
useDomainCheck($domain) Указывает валидатору проверить имя хоста на корректность.
getDomainCheck() Возвращает true, если включена проверка имени хоста.
setHostnameValidator($hostnameValidator) Добавляет валидатор для проверки части эл. адреса, содержащей имя хоста.
getHostnameValidator() Возвращает валидатор, использованный для проверки части эл. адреса, содержащей имя хоста.
setAllow($allow) Задает допустимые типы имен хостов в адресе электронной почты.
getAllow() Возвращает допустимые типы имен хостов.
useMxCheck($mx) Определяет, осуществлять ли проверку MX-записи через DNS.
getMxCheck($mx) Возвращаетtrue, если включен режим проверки MX.
useDeepMxCheck($deep) Определяет, использовать ли глубокую проверку для MX-записей.
getDeepMxCheck() Возвращает true, если включен режим глубокой проверки MX; иначе возвращает false.
isMxSupported() Возвращает true, если системой поддерживается проверка MX через PHP-функцию getmxrr(); иначе возвращает false.
getMXRecord() После проверки возвращает найденную MX-запись.

Как видите из таблицы выше, валидатор EmailAddress, вдобавок к методам isValid() и getMessages(), предоставляет метод конструктора, которому вы можете при желании передать полный список опций для инициализации валидатора.

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

Класс EmailAddress также предоставляет большое количество методов, которые можно использовать для задания определенных опций валидатора.

Метод useDomainCheck() указывает, нужно ли проверять имя хоста на корректность или нет. По умолчанию, эта проверка включена. Метод setAllow() позволяет указать, какие типы имен хостов разрешены. Вы можете передать комбинацию ИЛИ констант с префиксом ALLOW_ 31 методу setAllow():

31) Константы с префиксом ALLOW_ предоставляются валидатором Hostname.

Валидатор EmailAddress внутренне использует валидатор Hostname для проверки части имени хоста адреса электронной почты. Вы также можете добавить пользовательский валидатор имени хоста, используя метод setHostnameValidator(), однако вам вряд ли понадобится это делать.

Метод useMxCheck() определяет, нужно ли валидатору подключаться к хосту отправителя и запрашивать у DNS-сервера MX-запись(-и). Если у сервера нет MX-записей, валидация будет неудачной. Кроме этого, вы можете использовать метод useDeepMxCheck(), чтобы валидатор сравнивал адреса почтовых серверов, полученных из MX-записей, с черным списком зарезервированных доменных имен и осуществлял дополнительную проверку для каждого обнаруженного адреса.

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

Ниже мы приведем образцы кода, показывающие два эквивалентных способа создания экземпляра валидатора EmailAddress вручную, задания его опций и проверки входного значения:

Пример 1. Передача опций методу конструктора.

<?php
// Определяем псевдоним для имени класса валидатора (опционально).
use Zend\Validator\EmailAddress;
use Zend\Validator\Hostname;

// Создаем экземпляр валидатора, передавая опции конструктору.
$validator = new EmailAddress([
		'allow' => Hostname::ALLOW_DNS|Hostname::ALLOW_IP|Hostname::ALLOW_LOCAL,
		'mxCheck' => true,
		'deepMxCheck' => true
	]);

// Валидируем адрес эл. почты.
$isValid = $validator->isValid('name@example.com'); // Возвращает true.
$isValid2 = $validator->isValid('abc'); // Возвращает false.

if(!$isValid2) {
  // Получаем сообщения об ошибках в случае неудачной валидации.
  $errors = $validator->getMessages();
}

Во фрагменте выше мы создаем объект валидатора EmailAddres с помощью оператора new (строка 7). Мы передаем конструктору массив опций. Чтобы разрешить адресу эл. почты быть либо доменным именем, либо IP-адресом, либо адресом локальной сети мы используем ключ allow. Кроме этого, мы используем mxCheck и deepMxCheck, чтобы включить проверку соответственно проверки MX-записи и глубокую проверку MX-записи.

В строке 14 мы вызываем метод isValid() и передаем ему строковое значение "name@example.com" для проверки. Ожидаемый результат этого вызова - булевое true.

В строке 15 мы передаем валидатору строковое значение "abc". Процедура валидации должна быть неудачной (возвращается false). Затем сообщения об ошибках извлекаются с помощью метода getMessages() (строка 19).

Пример. Без передачи опций конструктору.

<?php
// Определяем псевдоним для имени класса валидатора (опционально).
use Zend\Validator\EmailAddress;
use Zend\Validator\Hostname;

// Создаем экземпляр валидатора.
$validator = new EmailAddress();

// Настраиваем валидатор (опционально).
$validator->setAllow(
       Hostname::ALLOW_DNS|Hostname::ALLOW_IP|Hostname::ALLOW_LOCAL);
$validator->useMxCheck(true);
$validator->useDeepMxCheck(true);

// Валидируем адрес эл. почты.
$isValid = $validator->isValid('name@example.com'); // Returns true.
$isValid2 = $validator->isValid('abc'); // Returns false.

if(!$isValid2) {
  // Получаем сообщения об ошибках в случае неудачной валидации.
  $errors = $validator->getMessages();
}

Во фрагменте выше мы создаем объект валидатора EmailAddres с помощью оператора new (строка 7).

В строках 10-13 мы настраиваем валидатор. Мы вызываем метод setAllow(), чтобы разрешить адресу эл. почты быть либо доменным именем, либо IP-адресом, либо адресом локальной сети. Помимо этого, мы используем mxCheck и deepMxCheck, чтобы включить проверку соответственно проверки MX-записи и глубокую проверку MX-записи.

В строке 16 мы вызываем метод isValid() и передаем ему строковое значение "name@example.com" для проверки. Ожидаемый результат этого вызова - булевое true.

В строке 17 мы передаем валидатору строковое значение "abc". Процедура валидации должна быть неудачной (возвращается false). Затем сообщения об ошибках извлекаются с помощью метода getMessages() (строка 21).

9.4.2. Способ 2. Использование обертки StaticValidator

Альтернативный способ ручного инстанцирования валидатора - с использованием класса StaticValidator. Класс StaticValidator - что-то вроде "заместителя" ("proxy"), который предназначен для автоматического инстанцирования валидатора, настройки и выполнения. Рассмотрим, например, как создать тот же валидатор EmailAddress, настроить его и вызывать его метод isValid():

<?php
// Создание и выполнение валидатора EmailAddress через "заместителя" StaticValidator.
$validatedValue = \Zend\Validator\StaticValidator::execute('name@example.com', 
                    'EmailAddress', 
                    [
                      'allow' => 
                         Hostname::ALLOW_DNS|
                         Hostname::ALLOW_IP|
                         Hostname::ALLOW_LOCAL,
                      'mxCheck' => true,
                      'deepMxCheck' => true
                    ]);
						
// Ожидаемый результат - булевое true.

Класс StaticValidator предоставляет статический метод execute(), который принимает три аргумента: входное значение, имя валидатора, который нужно применить и массив опций для выбранного валидатора.

В строке 3 мы вызываем метод execute(), чтобы автоматически создать валидатор EmailAddress, вызвать его методы setAllowDns(), useMxCheck() и useDeepMxCheck(), а также передать входное значение методу isValid()`. Это крайне полезно, так как может быть выполнено одним вызовом.

StaticValidator не предоставляет возможности извлечь список ошибок в удобном для человеческого восприятия виде. Однако, так как StaticValidator предназначен для использования вне форм, а не отображения результатов человеку, это не кажется большим недостатком.

9.4.3. Способ 3. Использование описания в виде массива

При использовании валидаторов для правил валидации формы, как правило, объект валидатора не создают явно, как мы сделали это в предыдущем разделе; вместо этого настройки передаются в виде массива классу фабрики, автоматически создающему валидатор, который затем можно настроить. Мы уже сталкивались с подобным способом при добавлении правил валидации для формы обратной связи в главе Получение введенных пользователем данных с помощью форм.

В качестве примера покажем, как создать все тот же валидатор EmailAddress с помощью фабрики:

<?php
// Предполагается, что вы вызываете следующий код внутри метода
// addInputFilter() модели формы.

$inputFilter->add([
  // ...  
  'validators'  => [
    [
      'name' => 'EmailAddress',
      'options' => [
        'allow' => \Zend\Validator\Hostname::ALLOW_DNS,
        'useMxCheck' => false,
        'useDeepMxCheck' => false,
      ],
    ],
  ],                
  // ...
]);

В фрагменте кода выше мы вызываем метод add(), предоставляемый классом-контейнером InputFilter (строка 5). Метод add() принимает массив, который имеет ключ validators. Как правило, валидаторы регистрируются под этим ключом (строка 7). Валидаторы, зарегистрированные под этим ключом, вставляются в цепь валидаторов в том же порядке, что и в списке.

Конфигурация валидатора обычно состоит из имени - name (строка 9) и опций - options (строка 10). Имя - это полностью определенное имя класса валидатора (например, \Zend\Validator\EmailAddress), либо его псевдоним (EmailAddress). options - это массив, состоящий из опций конкретного валидатора. Когда класс фабрики инстанцирует валидатор, он передает список опций методу конструктора валидатора, а конструктор при необходимости инициализирует валидатор.


Top