Статьи

Zend_Validate для победы

Zend_Validate является компонентом Zend Framework, который предоставляет классы валидации, которые позволяют из стандартной длины проверять длины строк и незнакомые свойства, такие как соответствие регулярным выражениям или стандарту для штрих-кодов.

Zend_Validate довольно своеобразен в отношении других механизмов валидации, таких как встроенная поддержка Doctrine 1 для валидации типов значений столбцов базы данных. На самом деле Zend_Validate содержит много специфичных для домена валидаторов , которые были внесены пользователями платформы за последние годы. Поскольку эти виды проверки сложны и подвержены ошибкам, может быть полезно иметь их в вашем распоряжении в уже установленной платформе, например, чтобы получить структуру MVC.

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

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

Составной шаблон (он же цепочки валидации)

Таким образом, эти типы проверки становятся товаром в Zend Framework. Тем не менее, я думаю, что большая часть возможностей Zend_Validate заключается в объектно-ориентированном интерфейсе, который он предоставляет, а не в специфичном для домена коде, который довольно странно найти в платформе, а не в специализированной библиотеке.

Zend_Validate_Interface, единственный интерфейс компонента, имеет много реализаций. Некоторые из них, такие как валидаторы Float или InArray, можно написать за 5 минут, обернув PHP-функции или используя регулярные выражения (если, конечно, вы знаете правильное регулярное выражение для пользователя).

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

Цепочка валидаторов является экземпляром класса Zend_Validate и является реализацией шаблона Composite: если вы зависите от Zend_Validate_Interface в своем клиентском коде, вам никогда не придется беспокоиться, если вы передали один валидатор (Zend_Validate_ * instance) или цепочка (экземпляр Zend_Validate), или даже цепочка цепочек .

Примеры

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

<?php
ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . '/home/giorgio/code/zftrunk/library');
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();

class ZendValidateTest extends PHPUnit_Framework_TestCase
implements Zend_Validate_Interface
{
public function testAlphanumericValidation()
{
$validator = new Zend_Validate_Alnum();
$this->assertTrue($validator->isValid('giorgio88'));
$this->assertFalse($validator->isValid('giorgio 88'));
}

public function testAlphanumericValidationWithSpaces()
{
$validator = new Zend_Validate_Alnum();
$validator->setAllowWhiteSpace(true);
// or:
// new Zend_Validate_Alnum(array(
// 'allowWhiteSpace' => true
// ));
// setters and constructor options are equivalent
// and setters Api documentation describes which options
// are accepted (unified constructor)

$this->assertTrue($validator->isValid('giorgio 88'));
$this->assertFalse($validator->isValid('[email protected]'));
}

public function testBetweenValidation()
{
$validator = new Zend_Validate_Between(array(
'inclusive' => true,
'max' => 10,
'min' => 5
));

$this->assertTrue($validator->isValid(5));
$this->assertFalse($validator->isValid(4));
$this->assertTrue($validator->isValid(10));
$this->assertFalse($validator->isValid(11));
}

public function testEmailAddress()
{
$validator = new Zend_Validate_EmailAddress();

$this->assertTrue($validator->isValid('[email protected]'));
$this->assertFalse($validator->isValid('name.email.com'));
}

public function testIpValidation()
{
$validator = new Zend_Validate_Ip();

$this->assertTrue($validator->isValid('127.0.0.1'));
$this->assertFalse($validator->isValid('568.0.0.1'));
}

public function testInArray()
{
$validator = new Zend_Validate_InArray(array(
'haystack' => array('blue', 'red', 'green')
));

$this->assertTrue($validator->isValid('red'));
$this->assertFalse($validator->isValid('yellow'));
}

public function testRegex()
{
$validator = new Zend_Validate_Regex(array(
'pattern' => '/^[A-Z]*$/'
));

$this->assertTrue($validator->isValid('UPPER'));
$this->assertFalse($validator->isValid('lower'));
}

// an example from the manual, expanded a lot
public function testValidatorsChaining()
{
// let's say a nickname for our website should be like this:
$validatorChain = new Zend_Validate();
$validatorChain->addValidator(new Zend_Validate_NotEmpty(),
$breakChainOnFailure = true)
->addValidator(new Zend_Validate_StringLength(array(
'min' => 6
)))
->addValidator(new Zend_Validate_Alnum())
->addValidator($this);

// NotEmpty fails, and no one else is called:
$this->assertFalse($validatorChain->isValid(''));
// StringLength fails:
$this->assertFalse($validatorChain->isValid('nick'));
// Alnum fails:
$this->assertFalse($validatorChain->isValid('nickname%'));
// Passes all checks:
$this->assertTrue($validatorChain->isValid('giorgiosironi'));
return $validatorChain;
}

/**
* @depends testValidatorsChaining
*/
public function testChainsCanBeElementsOfOtherChains($originalValidatorChain)
{
$validatorChain = new Zend_Validate();
$validatorChain->addValidator($originalValidatorChain)
->addValidator($this);

// still not valid
$this->assertFalse($validatorChain->isValid(''));
$this->assertFalse($validatorChain->isValid('nick'));
$this->assertFalse($validatorChain->isValid('nickname%'));
// additional check from $this->isValid():
$this->assertFalse($validatorChain->isValid('theAdministrator'));
// still passes:
$this->assertTrue($validatorChain->isValid('giorgiosironi'));
}

/**
* Implementing Zend_Validate_Interface.
* Excludes reserved nicknames, like the ones containing 'admin'.
*/
public function isValid($value)
{
return !stristr($value, 'admin');
}

/**
* Required by the interface for displaying error messages,
* but not called nor explained here.
*/
public function getMessages()
{
return array('reserved');
}
}