Работа с валидаторами форм в Zend Framework
В комментариях к статье “Работа с формами в Zend Framework“, Сергей задал вопрос о реализации проверки уникальности логина пользователя и совпадения пароля и подтверждения. Так как же это реализовать!
Одним из вариантов является создание валидаторов, отвечающих требованиям наших задач. Давайте сначала создадим валидатор, проверяющий наличие в базе данных пользователя с заданным логином.
Валидатор текстового поля
Сначала создадим папку, где будут находится наши валидаторы. В моем случае - это vaniashev/validators. В эту папку поместим php файл Login.php, содержащий следующий код:
class Vaniashev_Validator_Login extends Zend_Validate_Abstract
{
const LOGIN_EXISTS = 'exists';
protected $_messageTemplates = array(
self::LOGIN_EXISTS => 'Duplicate login'
);
public function isValid($value, $context = null)
{
if (!userExists($value)){
return true;
}
$this->_error(self::LOGIN_EXISTS);
return false;
}
...
}
В коде видно, что если метод, проверяющий наличие введенного логина в базе данных (userExists()), возвращает true, то вызывается функция _error() из Zend_Validate_Abstract, которой передается сообщение об ошибке. Причем передается не само сообщение, а константа, идентифицирующая его. В дальнейшем, это сообщение будет отображено рядом с текстовым полем, для ввода логина. Соответствия между константами и текстом сообщения храняться в массиве $_messageTemplates. Поле ввода логина создается так:
$login = new Zend_Form_Element_Text("login");
$login->addValidator(new Vaniashev_Validator_Login());
$form->addElement($login);
Валидатор сопадения пароля и подтверждения
Для реализации этого валидатора, необходимо воспользоваться параметром $context метода isValid() валидатора. Этот параметр содержит данные, пришедшие с формы. Код валидатора:
class Vaniashev_Validator_SamePassword extends Zend_Validate_Abstract {
const PASSWORDS_NOT_EQUAL = 'ne';
private $pwd1;
private $pwd2;
function __construct($pwd1, $pwd2) {
$this->pwd1 = $pwd1;
$this->pwd2 = $pwd2;
}
protected $_messageTemplates = array (
self :: PASSWORDS_NOT_EQUAL => 'Error'
);
public function isValid($value, $context = null) {
if ($context[$this->pwd1] == $context[$this->pwd2]) {
return true;
}
$this->_error(self :: PASSWORDS_NOT_EQUAL);
return false;
}
}
Как вы заметили, при создании объекта валидатора, ему передаются имена полей для ввода паролей, эквивалентность которых будет проверяться. Поля ввода пароля создаются следующим образом:
$p1 = new Zend_Form_Element_Password("p1");
$p2 = new Zend_Form_Element_Password("p2");
$p1->addValidator(new Vaniashev_Validator_SamePassword("p1","p2"));
$form->addElement($p1);
$form->addElement($p2);
В статье были представлены приемы создания своих валидаторов в ZendFramework. Жду ваших вопросов!

31 Окт 2008 в 4:56 пп
Большое спасибо. Теперь всё стало гораздо понятнее. Один вопрос: в каких случаях выводятся значения констант PASSWORDS_NOT_EQUAL и LOGIN_EXISTS заданные по умолчанию?
31 Окт 2008 в 5:32 пп
Если я правильно понял ваш вопрос, в случае вызова функции _error() без параметров, выводится первое сообщение из списка $_messageTemplates
15 Апр 2009 в 4:21 пп
Валидатор для паролей я реализовал несколько иначе