Написание custom валидатора для Zend_Form

Очень удобная вещь – Zend_Form. Данный компонент предоставляет множество возможностей, таких как фильтрация и валидация данных формы. Zend_Form имеет ряд собственных валидаторов и фильтров, но он достаточно гибок, и есть возможность создавать свои классы для валидации.

Рассмотрим на примере создание собственного валидатора для формы регистрации.

Возьмем простейшую форму для регистрации, с минимальным набором полей:

  • логин
  • email
  • пароль
  • пароль повторно

Требования к полям:

  1. Логин – обязательное поле, строка из цифро-буквенных символов длиною от 3 до 15 символов, уникальное.
  2. email – обязательное поле, имеет правильный формат, уникальное.
  3. Пароль – обязательное поле, строка из любых символов, не короче 6 символов
  4. Пароль повторно – поле должно совпадать с полем ‘пароль’.

Исходя их требований, можно сделать вывод, что нам нужно написать 3 собственных валидатора:

  1. Проверка уникальности логина.
  2. Проверка уникальности email.
  3. Проверка совпадения паролей.

Для создания custom validator, нужно наследовать класс от абстрактного Zend_Validate_Abstract, и реализовать в нем метод isValid.

В своих проектах валидаторы я храню в директории models/validator.

Создание валидатора уникальности логина

Создаем новый файл models/validator/UniqueNickname.php

Создание валидатора уникальности email

Создаем новый файл models/validator/UniqueEmail.php

Создание валидатора для паролей

С этим валидатором дела обстоят интереснее. Создаем новый файл models/validator/EqualValues.php.

Форма регистрации

Теперь создаем непосредственно саму форму регистрации (models/form/Register.php)

При добавлении валидатора для паролей нужно вызывать метод setAllowEmpty со значением false. Это делается для того чтобы валидатор паролей срабатывал при пустом значении “Пароль повторно”.

Сам процесс регистрации не входит в рамки данной статьи, возможно позже напишу продолжение данной статьи.

  • lcf

    А зачем у вас проверка
    if (is_string($context) && ($value === $context)) {
    ? ^_^

    Что будет если не строка?

  • admin

    🙂
    Эта часть была скопирована с примера, который приводил san.
    Но, во всяком случае $context будет строкой, так что проверку is_string можно убрать.
    Спасибо за замечание.

  • Вместо того что бы писать для каждого поля свой валидатор на уникальность, я использую универсальный http://zendframework.ru/articles/zend-validate-examples#nodbexists

  • admin

    Согласен, а то получилось дублирование кода.
    Спасибо за совет.

  • Зендом увлекся? А я вот на симфони)) похоливарим?

  • admin

    Не то слово увлекся!
    С утра до вечера – один Zend Framework 🙂
    Холиварить нет смысла, т.к. symfony я тоже люблю!

  • terix

    Очень интересно, почему валидатор лежит именно в models/validator/ а не где – то ещё. Это продиктовано вкусовыми пристрастиями или суровой необходимостью?
    Интересно также почему форма лежит в models/form. В зендовском туториале формы кладут в application/form вроде.

  • Вот черт, формы через php объекты действительно рулят, надо и мне переучить себя ). Ко всему вышенаписанному хочу добавить, что в самом процессе регистрации я бы не надеялся на метод User::checkLogin() или User::checkEmail(), а ловил бы Exception, который генерится при попытке вставки в таблицу дублированных данных (поля с UNIQUE INDEX)

  • admin

    @terix:
    В принципе, разработчик сам в праве выбирать место для своих классов – мне так удобнее.

  • admin

    @[YS.PRO]:
    ну на счет Exception: по-моему это слишком… По крайней мере такого еще нигде не встречал.

  • Хыиуду

    Не знаю, почему, но у меня $this->_error($error); не хотело работать. Сделал так: $this->_messages[]=$error;