Валидатор форм (PHP)
#32
Отправлено 10 декабря 2007 - 18:20
#34
Отправлено 10 декабря 2007 - 23:40
<?php Пример формы: $_POST = Array( [comment] => Комментарий [register] => Array( [name] => Имя [company] => Фирма [address] => Адрес [city] => Город [indeks] => Индекс [phone] => Телефон [email] => Мыло [password] => Пароль [password2] => Повтор пароля ) ) Нет времени делать примеры, вот кое-что накорябал, классы все прокоментированы почти до каждой строки // Пример использования $validator = new MultiformValidator(); if ( $validator->hasValidated() ) { // Форма прошла проверку... } /** * Валидация нескольких форм в одной */ class MultiformValidator extends FormValidator { protected function configure() { // Тут указываем какие формы будем использовать $this->addForm( 'register' ); } protected function execute() { // По-умолчанию так же обрабатываются все поля 1го уровня $this->addElement( 'comment' ) // Комментарий ->addFilter( 'maxLenght', null, array( 100 ) ); // Макс. длина поля 100 символов } protected function executeRegister() { $this->addElement( 'name' ) ->setRequired(); $this->addElement( 'company' ); $this->addElement( 'address' ) ->setRequired(); $this->addElement( 'city' ) ->setRequired(); $this->addElement( 'indeks' ) // тут просто пример своего правила ->setRequired() ->addCallback( 'Indeks', 'Индекс должен состоять только из цифр' ); $this->addElement( 'phone' ); $this->addElement( 'email' ) ->setRequired() ->addCallback( 'email', 'Неверный формат Email адреса' ) ->addCallback( 'hasRegisteredEmail', 'Такой Email уже зарегистрирован' ); $this->addElement( 'password' ) ->setRequired() ->addCallback( 'lenght', 'Длина пароля может быть от 6 до 12 символов', array( 6, 12 ) ); $this->addElement( 'password2' ) ->addCompare( 'password', 'Пароли должны совпадать' ); } public function validateIndeks( $indeks ) { if ( ! is_numeric( $indeks ) ) { return false; } } public function hasRegisteredEmail( $email ) { if ( емайл не зарегистрирован в системе ) { return false; } } }
P.S. всё очень гениально просто, никаких выдуманых сложностей. Гибкость реализуется только за счёт своих callbackRaw функций (что это такое - в комментариях FormValidatorElement). Есть в планах сделать так, что форма будет задаваться не как просто набор имён полей, а так же как тип инпут, селект и т.п. Правда, это может свести на нет всю текущую простоту...
Прикрепленные файлы
Сообщение изменено: Setor (14 декабря 2007 - 15:34 )
#36
Отправлено 14 декабря 2007 - 18:30
Да нет, просто использовать чужие разработки всегда сложно... Я иногда заглядываю в свой старый код и сомневаюсь, что это я его когда-то писал. Настолько сложные алгоритмы, проверки, формулы какие-то и сортировки, диву даёшься Чтобы разобраться в таком коде либо нужен комментарий каждой строчки, либо пару часов на дебаггинг (пошаговый Debug в Zend Studio).Я наверно тупой, но я так и не вкурил, как оседлать этого зверька)))
Основная суть этих классов заключается лишь в том, что:
1) Они знают какие входящие переменные им нужны
2) Они знают как их отфильтровать
3) Они знают какую callback функцию к ним применить
4) Они оставляют результат проверки и сообщения. Каждый элемент формы знает о том, был ли он проверен и есть ли у него какие-то сообщения об ошибках.
Например, можно отрисовать форму через шаблонизатор, выделив ошибки:
/* * @var $validator FormValidator * @var $formName Имя формы (если нет массивов в $_POST, оставить пустым) */ private function fillForms( $validator, $formName = '' ) { foreach ( $validator->getElements( $formName ) as $element ) { $this->templateEngine->assign( $formName . '_' . $element->getName(), $element->getValue( true ) ); // getValue( true ) = htmlspecialchars( $value ) if ( ! $element->hasValidated() ) // Если проверка поля не прошла { // Поля с ошибками выделяем цветом $this->templateEngine->( $formName . '_' . $element->getName() . '_error', ' style="background-color: red"' ); // Если есть сообщения об ошибках, тоже выводим if ( $element->hasMessages() ) { $this->templateEngine->( $formName . '_' . $element->getName() . '_message', '<br/>' . $element->getFirstMessage() ); } } } }
Основная мощь заключается в callback функциях, которые могут делать что угодно - обращаться к БД или на луну за инфой, производить какие-то вычисления или проверки. И так же у них есть возможность получить доступ к другим полям формы, т.е. можно строить зависимости.
P.S. я там обновил классы, в одном из них закралась ошибка, стояла неправильная проверка (вместо true проверяла false), из-за этого не выводились мессаги.
P.S. И ещё объект можно передать в Smarty и можно нарисовать очень красивый шаблончег
#37
Отправлено 14 декабря 2007 - 22:22
[comment] => Комментарий
[register] => Array(
[name] => Имя
[company] => Фирма
[address] => Адрес
[city] => Город
[indeks] => Индекс
[phone] => Телефон
[email] => Мыло
[password] => Пароль
[password2] => Повтор пароля
)
) ? ))) Постоянно ругается Fatal error: Class 'MultiformValidator' not found in тра ля ля .... уже всю голову сломал, ничего не выходит (( Можешь прислать запакованный пример как у тебя сделано ... ну, чтобы всё собрано было, а то ещё долго все сидеть будем и не фтыкать )
Сообщение изменено: Диверсант (14 декабря 2007 - 22:35 )
#38
Отправлено 14 декабря 2007 - 23:02
1) Это был пример массива, который получается после отправки формы. Саму форму мне было лень рисовать.
2) Сначала надо объявить класс, а потом его инициализировать. Т.е. суёшь его например, в отдельный файл и инклудишь + инклудишь ещё два приложенных класса. Это элементарно же) Пример прислать не могу, т.к. у меня всё зашито в приложении и я не могу из него выдрать.
Я эту тему создал для того, чтобы обсудить саму идею. Т.е. каждый должен сам для себя представить что ему нужно от валидатора форм. У меня просто нет времени делать примеры, основные моменты я изложил, код документирован, чуть ли не каждая строка...
Следующим этапом развития валидатора будет задание типов полей. Например, есть у нас форма с radio кнопками, на одну из них тыркнули, шаблонизатор должен её будет сам пометить. Т.е. форма будет полностью зашита в класс. И вроде как это всё реализовано в Pear Quick Form, но я его смотрел, так нифига и не понял
Диверсант, может есть смысл взять что-то более приспособленное для обычного народа?
#39
Отправлено 15 декабря 2007 - 00:26
Сообщение изменено: Диверсант (15 декабря 2007 - 00:29 )
#40
Отправлено 15 декабря 2007 - 00:57
Что там за ошибка у тебя такая? Сначала класс надо было определить, а потом его инициализировать)
Ладно, уговорил. Вот пример.
Ключевые моменты сюда, остальное я уже писал и оно в архиве
// Пример использования $validator = new MultiformValidator(); if ( $validator->hasValidated() ) { // Форма прошла проверку... print_r( $validator->getElements() ); } else { print_r( $validator->getMessages() ); } ?><hr> <table width="100%" border="0"> <form method="POST"> <?php foreach ( $validator->getElements( 'register' ) as $element ) { echo '<tr><td width="120">'; echo ucfirst( $element->getName() ); echo '</td><td>'; echo '<input type="text" size="40" name="register[' . $element->getName() . ']" value="' . $element->getValue(1) . '"' . ( $element->hasValidated() ? '' : ' style="background-color: yellow"' ) . '><br/>'; echo '</td></tr>'; } ?> <tr> <td>Комментарий</td> <td><textarea name="comment" rows = 10 cols = 60><?=$validator->getValue( 'comment', '' )?></textarea></td> </tr> <tr> <td> </td> <td><input type="submit"></td> </tr> </table> </form>
P.S. если будут ошибки, что ф-ция не найдена filter_var, а она есть по-дефолту только в пхп 5.2, как я уже говорил. Нужно из правил убрать фильтр проверки мыла. Т.е.
$this->addElement( 'email' ) ->setRequired() //->addCallback( 'email', 'Неверный формат Email адреса' ) ->addCallback( 'hasRegisteredEmail', 'Такой Email уже зарегистрирован' );
Вот так оно должно выглядеть: http://setor.net/validator/ (если у меня комп включен, ссылка будет работать)
Прикрепленные файлы
Сообщение изменено: Setor (15 декабря 2007 - 00:59 )
#41
Отправлено 15 декабря 2007 - 12:05
Сообщение изменено: Диверсант (15 декабря 2007 - 15:06 )
#42
Отправлено 18 декабря 2007 - 21:38
Я туда вложил только 1 или 2 функции проверки... Валидатор тем и замечателен, что позволяет легко внедрять практически любой необходимый функционал. Чтобы не юзать постоянно addCallback, можно написать делегирующие методы, которые сами будут вызывать addCallback. Типа ->minLenght( 'Минимум 3 символа!', 3 ). Для частоиспользуемых функций я так и делаю.Вот только не заметил, есть ли функция проверки на минимальное значение. Допустим мне надо, чтобы значение в поле было не менее 3 знаков, конечно можно поставить - ->addCallback('lenght', 'Минимум 3 символа!', array( 3, 100) ); , а то вот maxLenght есть, а min нету ) надо доделать ) А так, вообще замечтально )
ЗЫ: Диверсант, лучше не пользуйся исправлением, когда хочешь что-то добавить к 1му сообщению, иначе не приходит 2й раз извещение на мыло.
Народ, может кто знает ещё о каких-то популярных/удобных/функциональных похожих решениях?