framework.zend.com
Stable релиз 2.0 / 1.12

Валидация с помощью Zend_Validate, примеры использования

К комментариям

Содержание

Update (15.05.2009): С выходом Zend Framework 1.8 в стандартной поставке появились валидаторы Db_RecordExists и Db_NoRecordExists используйте их вместо аналогичных, приведенных ниже (их стоит рассматривать лишь в качестве учебного примера).

В этой заметке хочу поделиться с вами валидаторами, которые были написаны в процессе работы на второй частью туториала. Валидаторы выкладываются, в первую очередь, как примеры использования Zend_Validate, в учебных целях. Но, вы можете использовать их для своих целей, они распространяются под лицензией New BSD.

Валидатор пароля

Валидатор пароля - App_Validate_Password. Длина пароля должна быть в диапазоне 7-30 символов и пароль должен состоять из символов следующего набора ~!@#$%^&*()-_+=\/{}[].,?<>:;a-z0-9. Для реальных проектов этот валидатор нужно, как минимум, расширить до проверки на "сложность подбора".

 <?php

/**
* App_Validate_Password
*
* Валидация пароля
*
* @author Александр Махомет aka San для http://zendframework.ru
*
*/
class App_Validate_Password extends Zend_Validate_Abstract
{
/**
* Метка ошибки
* @var const
*/
const INVALID = 'passwordInvalid';

/**
* Метка ошибки
* @var const
*/
const INVALID_LENGTH = 'passwordBadLength';

/**
* Текст ошибки
* @var array
*/
protected $_messageTemplates = array(
self::INVALID => 'Value does not appear to be a valid password',
self::INVALID_LENGTH => 'Value should have more than 6 and less then 30 symbols'
);

/**
* Проверка пароля
*
* @param string $value значение которое поддается валидации
*/
public function isValid($value)
{
$this->_setValue($value);

$validatorStringLength = new Zend_Validate_StringLength(7, 30);

if (!$validatorStringLength->isValid($value)) {
$this->_error(self::INVALID_LENGTH);
return false;
}
elseif (!preg_match("/^[~!@#\\$%\\^&\\*\\(\\)\\-_\\+=\\\\\/\\{\\}\\[\\].,\\?<>:;a-z0-9]*$/i", $value)) {
$this->_error(self::INVALID);
return false;
}

return true;
}
}

Пример использования:

<?php
// Валидируем пароль
$password = 'mystrongpassword';
$validator = new App_Validate_Password($password);

Валидатор отсутствия записи в базе данных

Валидатор отсутствия записи в таблице базы данных - App_Validate_NoDbRecordExists. Например при регистрации необходимо проверить не занят ли определенный логин или электронная почта.

 <?php

/**
* App_Validate_NoDbRecordExists
*
* Проверка отсутствия записи в таблице
*
* @author Александр Махомет aka San для http://zendframework.ru
*
*/
class App_Validate_NoDbRecordExists extends Zend_Validate_Abstract
{

/**
* Метка ошибки
* @var const
*/
const RECORD_EXISTS = 'dbRecordExists';

/**
* Текст ошибки
* @var array
*/
protected $_messageTemplates = array(
self::RECORD_EXISTS => 'Record with value %value% already exists in table'
);

/**
* Имя таблица в которой будет происходить поиск записи
* @var string
*/
protected $_table = null;

/**
* Имя поля по которому будет происходить поиск значения
* @var string
*/
protected $_field = null;

/**
* Используемый адаптер базы данных
*
* @var object
*/
protected $_adapter = null;

/**
* Конструктор
*
* @param string $table Имя таблицы
* @param string $field Имя поля
* @param Zend_Db_Adapter_Abstract $adapter Адаптер базы данных
*/
public function __construct($table, $field, Zend_Db_Adapter_Abstract $adapter = null)
{
$this->_table = $table;
$this->_field = $field;

if ($adapter == null) {
// Если адаптер не задан, пробуем подключить адаптер заданный по умолчанию для Zend_Db_Table
$adapter = Zend_Db_Table::getDefaultAdapter();

// Если адаптер по умолчанию не задан выбрасываем исключение
if ($adapter == null) {
throw new Exception('No default adapter was found');
}
}

$this->_adapter = $adapter;
}

/**
* Проверка
*
* @param string $value значение которое поддается валидации
*/
public function isValid($value)
{
$this->_setValue($value);

$adapter = $this->_adapter;

$select = $adapter->select()
->from($this->_table)
->where($adapter->quoteIdentifier($this->_field) . ' = ?', $value)
->limit(1)
;
$stmt = $adapter->query($select);
$result = $stmt->fetch();

if ($result !== false) {
$this->_error();
return false;
}

return true;

}

}

Пример использования:

<?php
// Валидируем отсутствия электронной почты в таблице пользователей
$email = 'my@email.com';
$table = 'users';
// Используется адаптер БД установленный по умолчанию
$validator = new App_Validate_NoDbRecordExists($table, $email);

// Адаптер БД передается явно
$validator = new App_Validate_NoDbRecordExists($table, $email, $dbAdapter);

Валидатор существования записи в базе данных

Валидатор существования записи в таблице базы данных - App_Validate_DbRecordExists. Например при восстановлении пароля необходимо проверить на существование логин или почту в базе данных.

 <?php

/**
* App_Validate_DbRecordExists
*
* Проверка наличия записи в таблице
*
* @author Александр Махомет aka San для http://zendframework.ru
*
*/
class App_Validate_DbRecordExists extends Zend_Validate_Abstract
{

/**
* Метка ошибки
* @var const
*/
const RECORD_EXISTS = 'dbRecordNotExists';

/**
* Текст ошибки
* @var array
*/
protected $_messageTemplates = array(
self::RECORD_EXISTS => 'Record with value %value% not exists in table'
);

/**
* Имя таблица в которой будет происходить поиск записи
* @var string
*/
protected $_table = null;

/**
* Имя поля по которому будет происходить поиск значения
* @var string
*/
protected $_field = null;

/**
* Используемый адаптер базы данных
*
* @var object
*/
protected $_adapter = null;

/**
* Конструктор
*
* @param string $table Имя таблицы
* @param string $field Имя поля
* @param Zend_Db_Adapter_Abstract $adapter Адаптер базы данных
*/
public function __construct($table, $field, Zend_Db_Adapter_Abstract $adapter = null)
{
$this->_table = $table;
$this->_field = $field;

if ($adapter == null) {
// Если адаптер не задан, пробуем подключить адаптер заданный по умолчанию для Zend_Db_Table
$adapter = Zend_Db_Table::getDefaultAdapter();

// Если адаптер по умолчанию не задан выбрасываем исключение
if ($adapter == null) {
throw new Exception('No default adapter was found');
}
}

$this->_adapter = $adapter;
}

/**
* Проверка
*
* @param string $value значение которое поддается валидации
*/
public function isValid($value)
{
$this->_setValue($value);

$adapter = $this->_adapter;

$select = $adapter->select()
->from($this->_table)
->where($adapter->quoteIdentifier($this->_field) . ' = ?', $value)
->limit(1)
;
$stmt = $adapter->query($select);
$result = $stmt->fetch();

if ($result === false) {
$this->_error();
return false;
}

return true;

}

}

Пример использования такой же как для App_Validate_NoDbRecordExists.

Валидатор сравнения двух полей формы

Валидатор сравнения двух полей формы - App_Validate_EqualInputs. Можно использовать для проверки совпадения пароля и его подтверждения.

 <?php

/**
* App_Validate_EqualInputs
*
* Валидатор проверяет совпадение двух полей.
*
* @author Александр Махомет aka San для http://zendframework.ru
*/

class App_Validate_EqualInputs extends Zend_Validate_Abstract {

/**
* Метка ошибки
* @var const
*/
const NOT_EQUAL = 'stringsNotEqual';

/**
* Текст ошибки
* @var array
*/
protected $_messageTemplates = array(
self::NOT_EQUAL => 'Strings are not equal'
);

/**
* Название поля, с которым сравниваем
* @var string
*/
protected $_contextKey;

/**
* Конструктор валидатора
*
* @param string $key Название поля, с которым сравниваем
*/
public function __construct($key) {
$this->_contextKey = $key;
}


/**
*
* Сравнение полей
*
* Сравнение значения $value с $context[ $this->_contextKey ]
*
* @param string $value значение которое поддается валидации
*/
public function isValid($value, $context = null) {

$value = (string) $value;

if (is_array($context)) {
if (isset($context[$this->_contextKey]) && ($value === $context[$this->_contextKey])) {
return true;
}
}
else if (is_string($context) && ($value === $context)) {
return true;
}

$this->_error(self::NOT_EQUAL);

return false;
}
}

Пример использования совместно с Zend_Form:

$passwordApproveElement = new Zend_Form_Element_Password('password_approve', array(
'required' => true,
'label' => 'Подтвердите пароль:',
'maxlength' => '30',
));
// В конструктор передаем название поля, с которым будем сравнивать
$validator = new App_Validate_EqualInputs('password');
$passwordApproveElement->addValidator($validator);

В приведенных листингах кода я не подключал необходимые классы, например Zend_Validate_Abstract, об этом вам нужно позаботиться самим.

Буду рад услышать аргументированную критику. Для обсуждения кода создана тема на форуме.

Лучший способ следить за обновлениями сайта это подписаться на RSS
Если информация была полезной для вас, вы можете поддержать сайт.
Комментарии:
Василий 15.09.2009 22:22 #
Спасибо. на основе этих валидаторов я научился делать свои
Ответить
ya 27.07.2010 12:38 #
App_Validate_EqualInputs если подтверждение пароля пустое то он не работает. это нужно при редактировании: если пароль не введён, то он не должен меняться, если введён, то должен выдавать ошибку, если подтверждение не введено или введено но не совпадает, а ошибка выдаётся только если подтверждение не пустое и не совпадает с паролем, если пустое, то не выдаёт...
Ответить
denis 16.11.2011 10:09 #
Пример использования:

<?php
// Валидируем отсутствия электронной почты в таблице пользователей
$email = 'my@email.com';
$table = 'users';
// Используется адаптер БД установленный по умолчанию
$validator = new App_Validate_NoDbRecordExists($table, $email);

$email - должно быть название поля в таблице
Ответить
Уважаемые пользователи. Комментарии не для того чтобы:
  1. Спрашивать почему у вас не работает код, для этого есть тема форума закрепленная за статьей.
  2. Спрашивать как реализовать ту или иную функциональность, для этого необходимо создать свою тему на форуме.

Комментарии для того чтобы: высказать свое аргументированное мнение о статье, указать какие участки вызывают непонимание, что нужно исправить/улучшить, просто сказать спасибо.

Комментарии имеют древовидную структуру.
Если вы хотите ответить на определенный комментарий - нажмите на ссылку "Ответить" возле этого комментария.

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