10 Валидация
Phalcon\Validation - независимый компонент проверки, который проверяет произвольный набор данных. Этот компонент может использоваться для реализации правил проверки на объектах данных, которые не относятся к модели или коллекции.
В следующем примере показано его основное использование:
<?php use Phalcon\Validation; use Phalcon\Validation\Validator\Email; use Phalcon\Validation\Validator\PresenceOf; $validation = new Validation(); $validation->add( 'name', new PresenceOf( [ 'message' => 'Имя обязательное', ] ) ); $validation->add( 'email', new PresenceOf( [ 'message' => 'Требуется электронная почта', ] ) ); $validation->add( 'email', new Email( [ 'message' => 'Недействительный e-mail', ] ) ); $messages = $validation->validate($_POST); if (count($messages)) { foreach ($messages as $message) { echo $message, '<br>'; } }
Смешанная конструкция этого компонента позволяет вам создавать свои собственные валидаторы вместе с теми, которые предоставляются фреймворком.
Инициализация проверки
Цепи проверки можно инициализировать напрямую, просто добавив валидаторы в объект Phalcon\Validation. Вы можете поместить свои проверки в отдельный файл для лучшего повторного использования кода и организации:
<?php use Phalcon\Validation; use Phalcon\Validation\Validator\Email; use Phalcon\Validation\Validator\PresenceOf; class MyValidation extends Validation { public function initialize() { $this->add( 'name', new PresenceOf( [ 'message' => 'Имя обязательное', ] ) ); $this->add( 'email', new PresenceOf( [ 'message' => 'Требуется электронная почта', ] ) ); $this->add( 'email', new Email( [ 'message' => 'Недействительный e-mail', ] ) ); } }
Затем инициализируйте и используйте свой собственный валидатор:
<?php $validation = new MyValidation(); $messages = $validation->validate($_POST); if (count($messages)) { foreach ($messages as $message) { echo $message, '<br>'; } }
Validators
Phalcon предоставляет набор встроенных валидаторов для этого компонента:
Class | Explanation |
---|---|
Phalcon\Validation\Validator\Alnum | Проверяет, что значение поля является только буквенно-цифровым символом. |
Phalcon\Validation\Validator\Alpha | Проверяет, что значение поля является только буквенным символом. |
Phalcon\Validation\Validator\Date | Проверяет, что значение поля является допустимой датой. |
Phalcon\Validation\Validator\Digit | Проверяет, что значение поля - это только числовой символ. |
Phalcon\Validation\Validator\File | Проверяет, что значение поля является правильным файлом. |
Phalcon\Validation\Validator\Uniqueness | Проверяет, что значение поля уникально в соответствующей модели. |
Phalcon\Validation\Validator\Numericality | Проверяет, что значение поля является допустимым числовым значением. |
Phalcon\Validation\Validator\PresenceOf | Проверяет, что значение поля не является пустой или пустой строкой. |
Phalcon\Validation\Validator\Identical | Проверяет, что значение поля совпадает с заданным значением. |
Phalcon\Validation\Validator\Email | Проверяет, что это поле содержит допустимый формат электронной почты. |
Phalcon\Validation\Validator\ExclusionIn | Проверяет, что значение не входит в список возможных значений. |
Phalcon\Validation\Validator\InclusionIn | Проверяет, что значение находится в списке возможных значений. |
Phalcon\Validation\Validator\Regex | Проверяет, что значение поля соответствует регулярному выражению. |
Phalcon\Validation\Validator\StringLength | Проверяет длину строки. |
Phalcon\Validation\Validator\Between | Проверяет, что значение находится между двумя значениями. |
Phalcon\Validation\Validator\Confirmation | Проверяет, что значение совпадает с другим, присутствующим в данных. |
Phalcon\Validation\Validator\Url | Проверяет, что это поле содержит допустимый URL. |
Phalcon\Validation\Validator\CreditCard | Проверяет номер кредитной карты. |
Phalcon\Validation\Validator\Callback | Проверяет использование функции обратного вызова. |
В следующем примере объясняется, как создать дополнительные валидаторы для этого компонента:
<?php use Phalcon\Validation; use Phalcon\Validation\Message; use Phalcon\Validation\Validator; class IpValidator extends Validator { /** * Выполняет проверку * * @param Validation $validator * @param string $attribute * @return boolean */ public function validate(Validation $validator, $attribute) { $value = $validator->getValue($attribute); if (!filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) { $message = $this->getOption('message'); if (!$message) { $message = 'IP недействителен'; } $validator->appendMessage( new Message($message, $attribute, 'Ip') ); return false; } return true; } }
Важно, чтобы валидаторы возвращали действительное логическое значение, указывающее, была ли проверка успешной или нет.
Валидатор обратного вызова
Используя Phalcon\Validation\Validator\Callback , вы можете выполнить пользовательскую функцию, которая должна возвращать boolean или новый класс проверки, который будет использоваться для проверки того же поля. Возвращая true
валидаця - успешна, возврат false
означает, что проверка не прошла. При выполнении этого валидатора Phalcon передает данные в зависимости от того, что это такое - если это сущность, то объект будет передан, иначе данные. Пример:
<?php use \Phalcon\Validation; use \Phalcon\Validation\Validator\Callback; use \Phalcon\Validation\Validator\PresenceOf; $validation = new Validation(); $validation->add( 'amount', new Callback( [ 'callback' => function($data) { return $data['amount'] % 2 == 0; }, 'message' => 'Принимается только четное количество продуктов' ] ) ); $validation->add( 'amount', new Callback( [ 'callback' => function($data) { if($data['amount'] % 2 == 0) { return $data['amount'] != 2; } return true; }, 'message' => "Вы не можете купить 2 продукта" ] ) ); $validation->add( 'description', new Callback( [ 'callback' => function($data) { if($data['amount'] >= 10) { return new PresenceOf( [ 'message' => 'Вы должны написать, почему вам нужна такая большая сумма.' ] ); } return true; } ] ) ); // будет возвращать сообщение с первого валидатора $messages = $validation->validate(['amount' => 1]); // будет возвращать сообщение от второго валидатора $messages = $validation->validate(['amount' => 2]); // будет возвращать сообщение из валидатора, возвращаемого третьим валидатором $messages = $validation->validate(['amount' => 10]);
Сообщения о проверке
Phalcon\Validation имеет подсистему обмена сообщениями, которая обеспечивает гибкий способ вывода или хранения сообщений проверки, сгенерированных во время процессов проверки.
Каждое сообщение состоит из экземпляра класса Phalcon\Validation\Message. Набор генерируемых сообщений можно получить с помощью метода getMessages()
. Каждое сообщение предоставляет расширенную информацию, такую как атрибут, который сгенерировал сообщение или тип сообщения:
<?php $messages = $validation->validate(); if (count($messages)) { foreach ($messages as $message) { echo 'Message: ', $message->getMessage(), "\n"; echo 'Field: ', $message->getField(), "\n"; echo 'Type: ', $message->getType(), "\n"; } }
Вы можете передать параметр message
для изменения / перевода сообщения по умолчанию в каждом валидаторе, даже если вы можете использовать подстановочный знак: :field
в сообщении, которое должно быть заменено меткой поля:
<?php use Phalcon\Validation\Validator\Email; $validation->add( 'email', new Email( [ 'message' => 'Недействительный e-mail', ] ) );
По умолчанию метод getMessages()
возвращает все сообщения, созданные во время проверки. Вы можете фильтровать сообщения для определенного поля с помощью метода filter()
:
<?php $messages = $validation->validate(); if (count($messages)) { // Отфильтровать только сообщения, сгенерированные для поля 'name' $filteredMessages = $messages->filter('name'); foreach ($filteredMessages as $message) { echo $message; } }
Фильтрация данных
Данные могут быть отфильтрованы до проверки, гарантируя, что вредоносные или неверные данные не будут проверены.
<?php use Phalcon\Validation; $validation = new Validation(); $validation->add( 'name', new PresenceOf( [ 'message' => 'Имя обязательное', ] ) ); $validation->add( 'email', new PresenceOf( [ 'message' => 'Требуется электронная почта', ] ) ); // Filter any extra space $validation->setFilters('name', 'trim'); $validation->setFilters('email', 'trim');
Фильтрация и дезинфекция выполняются с использованием компонента фильтра. Вы можете добавить дополнительные фильтры к этому компоненту или использовать встроенные.
События проверки
Когда проверки проводятся в классах, вы можете реализовать методы beforeValidation()
и afterValidation()
для выполнения дополнительных проверок, фильтров, очистки и т. Д. Если метод beforeValidation()
возвращает false
, проверка автоматически отменяется:
<?php use Phalcon\Validation; class LoginValidation extends Validation { public function initialize() { // ... } /** * Выполнено до проверки * * @param array $data * @param object $entity * @param Phalcon\Validation\Message\Group $messages * @return bool */ public function beforeValidation($data, $entity, $messages) { if ($this->request->getHttpHost() !== 'admin.mydomain.com') { $messages->appendMessage( new Message('Только пользователи могут войти в домен администрирования') ); return false; } return true; } /** * Выполнено после проверки * * @param array $data * @param object $entity * @param Phalcon\Validation\Message\Group $messages */ public function afterValidation($data, $entity, $messages) { // ... Добавление дополнительных сообщений или выполнение дополнительных проверок } }
Отмена проверки
По умолчанию все валидаторы, назначенные полю, проверяются независимо от того, был ли один из них неудачным или нет. Вы можете изменить это поведение, указав компонент проверки, который валидатор может остановить проверку:
<?php use Phalcon\Validation; use Phalcon\Validation\Validator\Regex; use Phalcon\Validation\Validator\PresenceOf; $validation = new Validation(); $validation->add( 'telephone', new PresenceOf( [ 'message' => 'Требуется телефон', 'cancelOnFail' => true, ] ) ); $validation->add( 'telephone', new Regex( [ 'message' => 'Требуется телефон', 'pattern' => '/\+44 [0-9]+/', ] ) ); $validation->add( 'telephone', new StringLength( [ 'messageMinimum' => 'Телефон слишком короткий', 'min' => 2, ] ) );
В первом валидаторе есть опция cancelOnFail
со значением true
, поэтому, если этот валидатор не работает, остальные валидаторы в цепочке не выполняются.
Если вы создаете настраиваемые валидаторы, вы можете динамически остановить цепочку валидации, установив параметр cancelOnFail
:
<?php use Phalcon\Validation; use Phalcon\Validation\Message; use Phalcon\Validation\Validator; class MyValidator extends Validator { /** * Выполняет проверку * * @param Phalcon\Validation $validator * @param string $attribute * @return boolean */ public function validate(Validation $validator, $attribute) { // Если значение атрибута является именем, мы должны остановить цепочку if ($attribute === 'name') { $validator->setOption('cancelOnFail', true); } // ... } }
Избегайте проверки пустых значений
Вы можете передать параметр allowEmpty
всем встроенным валидаторам, чтобы избежать проверки правильности при пустом значении:
<?php use Phalcon\Validation; use Phalcon\Validation\Validator\Regex; $validation = new Validation(); $validation->add( 'telephone', new Regex( [ 'message' => 'Требуется телефон', 'pattern' => '/\+44 [0-9]+/', 'allowEmpty' => true, ] ) );
Рекурсивная проверка
Вы также можете запускать экземпляры проверки в другом через метод afterValidation()
. В этом примере проверка экземпляра CompanyValidation
также проверяет экземпляр PhoneValidation
:
<?php use Phalcon\Validation; class CompanyValidation extends Validation { /** * @var PhoneValidation */ protected $phoneValidation; public function initialize() { $this->phoneValidation = new PhoneValidation(); } public function afterValidation($data, $entity, $messages) { $phoneValidationMessages = $this->phoneValidation->validate( $data['phone'] ); $messages->appendMessages( $phoneValidationMessages ); } }