OOP validators – класс для проверки параметров

slego

Новичок
Ну я же сказал, что

"Что проверить - не важно, ключевой момент здесь то, что нужно построить цепочку проверок:"

Хорошо, согласен, не очень удачный пример.
Допустим так: нужно проверить, что значение целое и находится в рамках чего-то:
PHP:
$vld->addRule('year', new IntValidator() ); 
$vld->addRule('year', new RangeValidator(array[1980, 1999]) ); 

$vld->validate($hash);
Ну или еще
Мне тяжело сейчас придумать, какую-либо более сложную цепочку. Но смысл в том, что группа проверок одна и та же и повторять ее для каждого проверяемого значения не очень удобно и красиво.
 

itprog

Cruftsman
2NetFly
действительно не подумал, тогда остается только передавать массив из того, что нужно проверять....
 
slego, в первом своем сообщение ты привел вполне логичное решение. Только я бы не вшивал параметры, а передавал бы их в конструктор нового валидатора.
 

slego

Новичок
2NetFly
Т.е. все, приведенное мной, актуально и имеет право на жизнь? ;)
Логичное то оно логичное, только вот хотелось бы структурно SafeStringValidator организовать так же как и обычные валидаторы..... Т.е. сделать из него правило.
Только геморройно, наверное, все это :) Стоит ли заморачиваться. Как ты это реализовываешь? Или просто для каждого параметра идет список правил проверки?

Вот, кстати, еще одна статейка
http://inform.p-stone.ru/libr/internet/prog/php/data/public7/
Интересная идея, может быть встречалась.
Проверка реализуется на основе паттерна Decorator - в результате визуально строится действительно ЦЕПОЧКА проверок.
 
В предыдущем сообщении не нового "валидатора", а "нового правила".

SafeStringValidator и будет обычным правилом, в чем проблема? Пусть наследует базовый класс, как и все правила, и использует функциональность LengthsValidator и RegexpValidator. Не помню как в WACT, но у меня такое возможно в виду независимости правил от валидатора.

У меня все описывается xml схемой и для каждого параметра список правил.
 

slego

Новичок
Т.е. в принципе, ты не сильно заморачиваешься, что, по сути, множествое полей имеет один и тот же список правил?

Автор оригинала: 2NetFly
У меня все описывается xml схемой и для каждого параметра список правил.
А можешь примерчик сбросить, если не трудно (варианты: не жалко, не облом) :)
 

[sid]

Новичок
Ребята, а может стоит применить вездесущий декоратор!

PHP:
$value = new RangeValidator(new IntValidator($_POST['year']), array(1998, 2005))
Естественно метод получения самих данных (dataspace) можно изменить для удобства, что бы исключить ошибки с получением данных GPCS. А сам паттерн, мне кажется, отлично справляется с задачей! В конце концов он для таких случаев и был создан!
 

camka

не самка
А еще возможен вариант, когда необходимость проверки одного правила зависит от результата проверки другого или других правил. Тогда можно строить дерево зависимости правил.
 

slego

Новичок
Автор оригинала: [sid]
Ребята, а может стоит применить вездесущий декоратор!

PHP:
$value = new RangeValidator(new IntValidator($_POST['year']), array(1998, 2005))
Естественно метод получения самих данных (dataspace) можно изменить для удобства, что бы исключить ошибки с получением данных GPCS. А сам паттерн, мне кажется, отлично справляется с задачей! В конце концов он для таких случаев и был создан!
Я попробовал - как уже писал выше, понравилась сама запись в виде цепочки, но использовать на практике оказалось как-то не очень. Насколько я понял, для реализации паттерна декоратора нужно написать несколько простых валидаторов
IntValidator
FloatValidator
LengthValidator и т.д., которые принимают список обычных параметров (null, max, min, range)
А все остальные - должны быть чуть "сложнее", чтобы
дополнительным параметром могли принимать ссылку на валидатор...
Да и при использовании автоматической проверки (xml-описания форм, полей), использование декоратора затрудняет проверку, кажется :)
 

!diss

Новичок
Уважаемые, извиняюсь за то что влезаю в Ваш разговор, но по моему мнению самое главное в данном классе не "уметь все" (что пытаетесь сделать Вы), а "установить стандарты".

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

Поскольку дополнительно необходимо связывать между собой несколько проверок:
1. Для каждой проверки должен быть определен текст ошибки
2. Обязательно чтобы функция возвращала только булевое значение.
3. Присутствовал класс для компоновки проверок в булевые группы

т.е. обработка формы должна происходить примерно так
PHP:
$form = new MainClass(array(&new FieldClass(ИмяПоля1, ДлинаПоля1, EMAIL_CONSTANT),  &new FieldClass(ИмяПоля1, 100, HTML_CONSTANT)...))
Третий параметр в конструкторе класса FieldClass будет ни что иное как линк на стандартный класс с определенным набором методов.

При обращении к свойствам класса MainClass мы можем автоматически исправить некоторые ошибки - свойство validData (например убрать HTML теги) и работать таким образом...
PHP:
if($form->ИмяПоля1->valid){
  echo $form->ИмяПоля1->validData;
}else{
  echo $form->ИмяПоля1->error;
}
 

whirlwind

TDD infected, paranoid
> Мне показалось, что хорошы бы создать ГРУППЫ ПРОВЕРОК.

Ну так наследуйте и уточняйте сущность

PHP:
class Atom_String extends Atom_Basic {
        protected function _registerConstraints(){
            $this->_setConstraint("minlen",
                new Constr_MinLen(WCMF_STRING_DEF_MINLEN) );
            $this->_check("minlen")->setNormalized();
            $this->_setConstraint("maxlen",
                new Constr_MaxLen(WCMF_STRING_DEF_MAXLEN) );
            $this->_check("maxlen")->setNormalized();
			$this->_setConstraint("eq_pattern",new Constr_EqPattern());
			$this->_setConstraint("ne_pattern",new Constr_NePattern());
            return true;
        }
}


class Atom_Integer extends Atom_Basic {
        protected function _registerConstraints(){
            $this->_setConstraint("ne_pattern",
                new Constr_NePattern("/[^\d\-]/"));
            $this->_check("ne_pattern")->setNormalized();
            $this->_setConstraint("minval",new Constr_MinVal(WCMF_INTEGER_MIN));
            $this->_check("minval")->setNormalized();
            $this->_setConstraint("maxval",new Constr_MaxVal(WCMF_INTEGER_MAX));
            $this->_check("maxval")->setNormalized();
            $this->_setConstraint("maxlen",new Constr_MaxLen(11) );
            $this->_check("maxlen")->setNormalized();
            return true;
        }

}

class Atom_Timestamp extends Atom_Basic {
	protected function _registerConstraints(){
		$this->_setConstraint("eq_pattern",
			new Constr_EqPattern("/^(\d+)-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])("
				." ([01]\d|2[0-3]):([0-5]\d):([0-5]\d))?\$/")
		);
		return true;
	}
}
А для удобства принимайте значения ограничителей в конструктор. И будет в результате

PHP:
// length check
new Atom_String(32,4)

// simple email check
new Atom_String(64,5,'/^[\._\-a-zA-Z0-9]+@[\._\-a-zA-Z0-9]{2,}$/') );

etc...
-~{}~ 10.04.06 14:47:

>itprog, а если на каждую из ошибок (регулярное выражение, длина) нужно выводить свое сообщение?

Флай, ты кстати, не мешай валидацию и обработку результатов.
 

itprog

Cruftsman
Флай, ты кстати, не мешай валидацию и обработку результатов.
Сам Флай :)
Не мешать?!? Покажи как ты разделяешь валидацию и обработку результатов (именно "вывод своего сообщение для каждой ошибки" (под выводом понимается получение текста ошибки))
 

whirlwind

TDD infected, paranoid
>Сам Флай

Да не, ты не понял, это я 2NetFly-ю на его пост. Твой ник туда случайно попал :)

По топику: я конкретно такой проблемой не заморачивался. У меня контроллеры на основе реквизитов. У каждого реквизита есть атрибут valid, который выставляется в false, если не удается транслировать в модель (считай - валидация провалена). И в шаблоне просто рядом с полем например так

PHP:
{? if !$some_requisite.valid ?} *{? /if ?}
-~{}~ 10.04.06 17:47:

Ну в любом случае, этим сообщениям не место в валидаторах. Есть понятие статуса валидации. Между статусом и сообщениями должен быть по крайней мере диспатчер.
 
Правила реализуют интерфейс:
RuleInterface
validate()
getCodes()

getCodes() возвращает список кодов (статусов) неудавшихся проверок. Чаще всего список содержит всего один элемент. Например, для RegexpRule это может быть только REGEXP_FAILED, для LengthRule – LENGTH_MIN либо LENGTH_MAX.

Правила и валидатор оперируют исключительно с кодами и не знаю ничего о сообщениях. Маппинг сообщений на коды реализуется в MessageDictionary.

а если на каждую из ошибок (регулярное выражение, длина) нужно выводить свое сообщение?
Здесь я имел в виду следующее: если программист воспользуется правилом
$validator->addRule(new RegexpRule("/^\w{10,20}$/"));
то в случае, если данные окажутся не валидными, программист не сможет сообщить, что именно с данными не так (поле пустое, содержит недопустимые символы, слишком короткое или слишком длинное). Разговор был именно об этом, а не о необходимости работать с сообщениями в валидаторе.

-~{}~ 10.04.06 22:51:

whirlwind, мы говорим о разных типах валидаторов. Ты - о констрейнтсах, я - о валидаторе параметров, без привязки к конкретным классам модели.

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

whirlwind

TDD infected, paranoid
Так rule это класс? Тогда какая разница к чему он привязан и как он называется constraint или rule если его результат (true|false)? :)

Вот вопрос возник, а что собой представляют REGEXP_FAILED, LENGTH_MIN, етц... Кем и когда они декларируются?
 

master_x

Pitavale XXI wieku
all
моя лепта... маленькая деталь конечно, но все же, не забывайте про использование ctype_* функций. А то я вижу тут регулярки типа [a-zA-Z0-9]
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
В ходе использования HTML_QuickForm я пришел к выводу, что его использование влечет за собой затраты на поддержку, сравнимые с пользой от его применения.
Почти все проекты я пишу для серверов, которые сам настраиваю, заранее знаю о допустимости использования фич последних версий.
HTML_QuickForm не всегда запускается на последних версиях, а править незнакомый код - не самое приятное занятие. Поэтому при выборе между необходимостью ждать обновления QuickForm, править самому или использовать простые решения, я выбрал последнее.

Поэтому я предпочел простое PHP5-ориентированное решение. Классу передается массив параметров с условиями проверок данных, а возвращает он массив "ошибок".
Массив ошибок предается через сессию в скрипт, который выводит форму вместе с данными.
По массиву ошибок легко создать нужные флаги в Смарти и вывести сообщения об ошибках.

Недостаток - трудность создания бинарной логики, генерация JS вынесена в плагины Smarty, отсутствие автоматизации многостраничных форм и прочие Bells&Whistles QuickForm.

Зато нет PEAR-овских проблем со скоростью и будущей совместимостью.
 

itprog

Cruftsman
grigori

Чего-то вообще не понял по теме ли это сообщение...
HTML_QuickForm это все же не тулза для валидации, а для генерации форм
 

tf

крылья рулят
может попробуем подвести итоги) что должен делать OOP validators
я лично использую свой класс. но никогда не отказываюсь использовать чужите идеи в необходимых случаях
 

texrdcom

Новичок
Помоему единственное правильно решения и максимально удобное созданно в
Zend Framework::Zend_InputFilter
Примения максимально удобно без лишнего наворота декоратора.
 
Сверху