Сейчас юзаю такой: PHP: <?php class KCZ_Validator { private $_Rules; public function __construct() { $this->_Rules = array(); } public function AddRule($RuleId, $RuleResult, $RuleMessage = '') { if(array_key_exists($RuleId, $this->_Rules)) { $this->_Rules[$RuleId][0] = ($this->_Rules[$RuleId][0] && $RuleResult); $this->_Rules[$RuleId][1] .= ($RuleMessage && (!$RuleResult)) ? ' ' . $RuleMessage : ''; } else { $this->_Rules[$RuleId] = array($RuleResult, (($RuleMessage && (!$RuleResult)) ? ' ' . $RuleMessage : '')); } } public function IsValid() { $Result = TRUE; foreach($this->_Rules as $Rule) { if(!$Rule[0]) { $Result = FALSE; } } unset($Rule); return $Result; } public function GetRules() { return $this->_Rules; } public function Clear() { $this->_Rules = array(); } } Регистрация: PHP: <?php $Validator = new KCZ_Validator(); $Validator->AddRule('reg_login_error', preg_match(USER_LOGIN_MATCH, KCZ_Request::Post('login')), KCZ_Translator::GetFormatText('M_LOGIN_RULE', USER_LOGIN_MINLENGTH, USER_LOGIN_MAXLENGTH)); $Validator->AddRule('reg_pswd_error', preg_match(USER_PSWD_MATCH, KCZ_Request::Post('pswd')), KCZ_Translator::GetFormatText('M_PSWD_RULE', USER_PSWD_MINLENGTH, USER_PSWD_MAXLENGTH)); $Validator->AddRule('reg_pswda_error', (KCZ_Request::Post('pswd') === KCZ_Request::Post('pswda')), KCZ_Translator::GetText('M_PASSWORDS_NOT_EQUAL')); if((KCZ_Str::Strlen(KCZ_Request::Post('email')) > 0)) { $Validator->AddRule('reg_email_error', (KCZ_Str::Strlen(KCZ_Request::Post('email')) < EMAIL_MAXLENGTH), KCZ_Translator::GetText('M_EMAIL_IS_TO_LONG')); } $Validator->AddRule('reg_email_error', (preg_match(EMAIL_MATCH, KCZ_Request::Post('email'))), KCZ_Translator::GetText('M_EMAIL_IS_WRONG')); if($Validator->IsValid()) { $Validator->AddRule('reg_login_error', (!User::IsLoginInUse(KCZ_Request::Post('login'))), KCZ_Translator::GetText('M_THIS_LOGIN_IS_ALREADY_IN_USE')); $Validator->AddRule('reg_email_error', (!User::IsEmailInUse(KCZ_Request::Post('email'))), KCZ_Translator::GetText('M_THIS_EMAIL_IS_ALREADY_IN_USE'));
вобщем, товарищи форумчане, считаю нужным попросить прощения за излишнюю грубость в общении, сказывается влияние субьективных факторов личностного характера, а так же андронного коллайдера в частности. Однако от своих слов я не отказываюсь в отношении Шока, его указаниях мне на чертей которых не было, мне это было крайне неприятно А так же по прежнему считаю подход к валидации излишне сложным и как следствие ущербным. так вот, решил поразмыслить всерьёз над реализацией итак, по сути у валидатора имеется три важных приемущества над обычными ифами: 1. Возможность быстро добавить дополнительную проверку 2. Вынос интерфейса обработчиков в отдельные функции, как следствие уменьшение кода 3. Возможность получить сразу лист ошибок однако с текущими подходами крайне неудобно работать с небольшими формами, если вдуматься оно мало чем будет отличаться от обычных ифов напомню, всё началось с синтаксического разбора строк(крайне ущербная реализация), потом перешло на массивы,потом переползло на объекты того или иного вида общее у всех этих реализаций было то что валидатором они называли сборщик ошибок, а тело(то где все функции валидатора) было его производной одноко понятно же что обрабатывает данные именно тело, а мы почему-то работаем с буфером ошибок, отсюда костыли реализации отсюда возникает вопрос, почему бы не работать с телом, а буфер сделать производной(впринципе как по определению и должно быть) в голове возникла такая реализация PHP: <? Validator::Run($_POST); // Массив с которым работаем по дефолту /*...*/ /* Для небольших форм, можно делать так*/ if(Validator_Body::NotEmpty(array("key1","key2"))) {} else { print "error"; } if(Validator_Body::NotEmpty(array("key1","key2"),null,$myArray)) {} else { print "error"; } // со своим массивом /*Для больших*/ Validator_Body::NotEmpty(array(/*...*/),"Ошибка тра та та"); Validator_Body::maxLength(30,array(/*...*/),"Ошибка тра та та"); if(!$errors=Validator::getErrors()){ }else{ } /* Свой валидатор - новое тело */ Validator_MyBody::myFunc(/*...*/); ?> плюсы думаю наглядны? простота, удобство, скорость
kostyl эм, а теперь представь себя на месте человека который будет этот код править после тебя(в теории =))
не понятно какой ущерб имеется в виду. а как тебе мой костыль. Честно говоря я не особо понял что ты хотел показать примерами - надо смотреть предыдущие посты или нет?
а чё - всё просто. Тупо собирает как ты говоришь ошибки. Можно быстро добавить условие, наглядно видно что с чем сравнивается. Да есть бок - писанина, одно условие в некольких местах, ну то и хер с ним.. )))
не надо смотреть предидущие в примерах хотел показать то что написал в теории =) а именно что валидатор это тело с функциями а не буферошибок и что работать должно именно это тело и что это упрощает реализацию и использование функционала
Mr.M.I.T., ты уж извини, но я не могу понять суть и преимущества твоей реализации (честно, без подъёбок). Вот к примеру — у нас есть 4 поля: nickname, passworfd, confirm, email, которые должны подпадать под следующие правила: Код (Text): UserReg: Nickname: NotEmpty: true Length: [4, 16] RegExp: /^[a-z]+$/i Password: NotEmpty: true MinLength: 3 PasswordStrength: true Confirm: NotEmpty: true Equals: Password Email: NotEmpty: true ValidEmail: true Если какое-то из полей — неправильное, то должна вывестись ошибка, если все правильно — юзер должен быть зареген. При том, если неправильно и Confirm и Email, то должны вывестись две ошибки. Можешь показать пример?
ты для полей правила пишешь, в результате у тебя дубликаты, я предлогаю поля для правил ну вот как бы я сделал PHP: <? Validator::Run($_POST); Validator_Body::NotEmpty(array("nickname","password","confirm","email"),"Поля тра та та не должны быть пустыми"); Validator_Body::LengthLimit(4,16,array("nickname"),"ошибка"); Validator_Body::minLength(3,array("password"),/*...*/); // некоторые методы не понял что значат, но суть думаю понятна if(!$err=Validator::getErrors()){ /* is valid */ }else{ /* errros */ } ?>
Не понятно, а что мешает написать так: PHP: <?php Validator::Run($_POST); // Массив с которым работаем по дефолту /*...*/ /* Для небольших форм, можно делать так*/ if(Validator::NotEmpty(array("key1","key2"))) {} else { print "error"; } if(Validator::NotEmpty(array("key1","key2"),null,$myArray)) {} else { print "error"; } // со своим массивом /*Для больших*/ Validator::NotEmpty(array(/*...*/),"Ошибка тра та та"); Validator::maxLength(30,array(/*...*/),"Ошибка тра та та"); if(!$errors=Validator::getErrors()){ }else{ Сам класс будет больше чтоли? Так же работаешь просто с одним объектом и всё. Не надо помнить что ошибки не в Validator_Body а в Validator. На Run очищаем предыдущие и делов то...
но вот она не намного сократит если для каждого поля разные условия, хотя условия можно тоже в массив запечатать и как говорит TheShock тоже не пойму как из: PHP: <?php Validator_Body::NotEmpty(array("nickname","password","confirm","email"),"Поля тра та та не должны быть пустыми"); пользователь поймет что nickname не пустой и email не пустой, ну или ты как поймешь что именно их он не заполнил?
это проблема из-за которой я начал говорить о неудобности валидаторов вцелом для маленьких форм я предложил делать так PHP: <? if(Validator_Body::NotEmpty(array("nickname","password","confirm","email"))) {} else {} это возврат назад, это ещё больше неудобно, проверено =) это будет заботой буфера, первое что на ум приходит PHP: <?php Validator_Body::NotEmpty(array("nickname","password","confirm","email"),"Поле {name} не должны быть пустыми");
Не увидел А какой новый, их можно на пальцах пересчитать. В принципе я думаю, что регулярные выражения обрабатывают много чего: notEmpty и maxLength можно заменить одной регуляркой: PHP: //Как в моем случае <?php define('USER_LOGIN_MINLENGTH', 2); define('USER_LOGIN_MAXLENGTH', 30); define('USER_LOGIN_MATCH', '/^[^\t]{' . USER_LOGIN_MINLENGTH . ',' . USER_LOGIN_MAXLENGTH . '}$/iu'); А насчет ошибок - ну что там надо, выдать их в массиве, ну вывести как нибудь еще. Так что я не особо думаю что буфер ошибок и валидация настолько велики чтобы разделять их. Ну может я еще не сильно с этим сталкивался так, чтобы меня это напрягло...
разделил я как раз чтобы легко включать новый функционал, какой хз какой, народ на этом помешан =) регулярки зло, хотя и вкусное цель соб-но максимально упростить реализацию, работу функционала, со всеми вытекающими
Последнее время меня терзает следующая штука - вот есть у меня модули. В модуле может обрабатыватся более одной сущьности как таковой. Т.е. скажем у меня есть модуль Events, у каждого события есть комменты. Хочется один раз настроить всё и что бы оно само заботилось о валидации. Что-то типа модели данных. Однако как привнести это в реальную жизнь, где на каждую сущьность не нужно плодить отдельный класс, точнее даже на каждую таблицу и припихивать грёбанный ActiveRecord или ещё что-нить подобное - не знаю... Использование Validator:: по 3-4 раза в одном модуле (в разных методах) уже заябывает. Хочется более централизовано что-ли...
Ты же все же не ради правил валидатора работаешь.... А ради полей. Поэтому разрывать поле по разным проверкам - не всегда есть хорошо.
Psih ну это уже более широкий вопрос... А как ты смотришь на то чтобы половину валидаций отсеивать на уровне правил метаданных в таблице. Пришел логин больше поля - нече не сохранилось - ошибка. Кстати а что ты имеешь в виду с актив рекородом - типа какие данные пришли такой и объект будет. Один хрен это всё где то описывать надо, и актив рекорд - как бы напрашивается сам собой.