За последние 24 часа нас посетили 22027 программистов и 1113 роботов. Сейчас ищут 674 программиста ...

form validation [готовое решение, принимаются замечания]

Тема в разделе "Решения, алгоритмы", создана пользователем Koc, 15 фев 2009.

  1. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Больше, больше ненависти!!!! (с)
     
  2. kostyl

    kostyl Guest

    Сейчас юзаю такой:
    PHP:
    1.  
    2. <?php
    3. class KCZ_Validator {
    4.     private $_Rules;
    5.  
    6.     public function __construct()
    7.     {
    8.         $this->_Rules = array();
    9.     }
    10.  
    11.     public function AddRule($RuleId, $RuleResult, $RuleMessage = '')
    12.     {
    13.         if(array_key_exists($RuleId, $this->_Rules)) {
    14.             $this->_Rules[$RuleId][0] = ($this->_Rules[$RuleId][0] && $RuleResult);
    15.             $this->_Rules[$RuleId][1] .= ($RuleMessage && (!$RuleResult)) ? ' ' . $RuleMessage : '';
    16.         }
    17.         else {
    18.             $this->_Rules[$RuleId] = array($RuleResult, (($RuleMessage && (!$RuleResult)) ? ' ' . $RuleMessage : ''));
    19.         }
    20.     }
    21.  
    22.     public function IsValid()
    23.     {
    24.         $Result = TRUE;
    25.         foreach($this->_Rules as $Rule) {
    26.             if(!$Rule[0]) {
    27.                 $Result = FALSE;
    28.             }
    29.         }
    30.         unset($Rule);
    31.         return $Result;
    32.     }
    33.  
    34.     public function GetRules()
    35.     {
    36.         return $this->_Rules;
    37.     }
    38.  
    39.     public function Clear()
    40.     {
    41.         $this->_Rules = array();
    42.     }
    43. }
    44.  
    Регистрация:
    PHP:
    1.  
    2. <?php
    3. $Validator = new KCZ_Validator();
    4. $Validator->AddRule('reg_login_error',
    5.                       preg_match(USER_LOGIN_MATCH, KCZ_Request::Post('login')),
    6.                       KCZ_Translator::GetFormatText('M_LOGIN_RULE', USER_LOGIN_MINLENGTH, USER_LOGIN_MAXLENGTH));
    7. $Validator->AddRule('reg_pswd_error',
    8.                       preg_match(USER_PSWD_MATCH, KCZ_Request::Post('pswd')),
    9.                       KCZ_Translator::GetFormatText('M_PSWD_RULE',  USER_PSWD_MINLENGTH, USER_PSWD_MAXLENGTH));
    10. $Validator->AddRule('reg_pswda_error',
    11.                       (KCZ_Request::Post('pswd') === KCZ_Request::Post('pswda')),
    12.                       KCZ_Translator::GetText('M_PASSWORDS_NOT_EQUAL'));
    13. if((KCZ_Str::Strlen(KCZ_Request::Post('email')) > 0)) {
    14.     $Validator->AddRule('reg_email_error',
    15.                           (KCZ_Str::Strlen(KCZ_Request::Post('email')) < EMAIL_MAXLENGTH),
    16.                          KCZ_Translator::GetText('M_EMAIL_IS_TO_LONG'));
    17. }
    18. $Validator->AddRule('reg_email_error',
    19.                       (preg_match(EMAIL_MATCH, KCZ_Request::Post('email'))),
    20.                       KCZ_Translator::GetText('M_EMAIL_IS_WRONG'));
    21. if($Validator->IsValid()) {
    22.     $Validator->AddRule('reg_login_error',
    23.                           (!User::IsLoginInUse(KCZ_Request::Post('login'))),
    24.                           KCZ_Translator::GetText('M_THIS_LOGIN_IS_ALREADY_IN_USE'));
    25.     $Validator->AddRule('reg_email_error',
    26.                            (!User::IsEmailInUse(KCZ_Request::Post('email'))),
    27.                           KCZ_Translator::GetText('M_THIS_EMAIL_IS_ALREADY_IN_USE'));
    28.  
     
  3. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    вобщем, товарищи форумчане, считаю нужным попросить прощения за излишнюю грубость в общении,
    сказывается влияние субьективных факторов личностного характера, а так же андронного коллайдера в частности.
    Однако от своих слов я не отказываюсь в отношении Шока, его указаниях мне на чертей которых не было, мне это было крайне неприятно
    А так же по прежнему считаю подход к валидации излишне сложным и как следствие ущербным.

    так вот, решил поразмыслить всерьёз над реализацией

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

    однако с текущими подходами крайне неудобно работать с небольшими формами, если вдуматься оно мало чем будет отличаться от обычных ифов
    напомню, всё началось с синтаксического разбора строк(крайне ущербная реализация), потом перешло на массивы,потом переползло на объекты того или иного вида

    общее у всех этих реализаций было то что валидатором они называли сборщик ошибок, а тело(то где все функции валидатора) было его производной
    одноко понятно же что обрабатывает данные именно тело, а мы почему-то работаем с буфером ошибок, отсюда костыли реализации

    отсюда возникает вопрос, почему бы не работать с телом, а буфер сделать производной(впринципе как по определению и должно быть)

    в голове возникла такая реализация

    PHP:
    1. <?
    2. Validator::Run($_POST); // Массив с которым работаем по дефолту
    3.  
    4. /*...*/
    5.  
    6. /* Для небольших форм, можно делать так*/
    7. if(Validator_Body::NotEmpty(array("key1","key2"))) {} else { print "error"; }
    8. if(Validator_Body::NotEmpty(array("key1","key2"),null,$myArray)) {} else { print "error"; } // со своим массивом
    9.  
    10. /*Для больших*/
    11.  
    12. Validator_Body::NotEmpty(array(/*...*/),"Ошибка тра та та");
    13. Validator_Body::maxLength(30,array(/*...*/),"Ошибка тра та та");
    14.  
    15. if(!$errors=Validator::getErrors()){
    16. }else{
    17. }
    18.  
    19. /* Свой валидатор - новое тело */
    20.  
    21. Validator_MyBody::myFunc(/*...*/);
    22.  
    23. ?>
    плюсы думаю наглядны?
    простота, удобство, скорость
     
  4. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    kostyl
    эм, а теперь представь себя на месте человека который будет этот код править после тебя(в теории =))
     
  5. kostyl

    kostyl Guest

    не понятно какой ущерб имеется в виду.
    а как тебе мой костыль. Честно говоря я не особо понял что ты хотел показать примерами - надо смотреть предыдущие посты или нет?
     
  6. kostyl

    kostyl Guest

    а чё - всё просто. Тупо собирает как ты говоришь ошибки. Можно быстро добавить условие, наглядно видно что с чем сравнивается. Да есть бок - писанина, одно условие в некольких местах, ну то и хер с ним.. )))
     
  7. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    не надо смотреть предидущие
    в примерах хотел показать то что написал в теории =)
    а именно что валидатор это тело с функциями а не буферошибок и что работать должно именно это тело
    и что это упрощает реализацию и использование функционала
     
  8. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    Mr.M.I.T., ты уж извини, но я не могу понять суть и преимущества твоей реализации (честно, без подъёбок).
    Вот к примеру — у нас есть 4 поля: nickname, passworfd, confirm, email, которые должны подпадать под следующие правила:
    Код (Text):
    1. UserReg:
    2.    Nickname:
    3.       NotEmpty: true
    4.       Length: [4, 16]
    5.       RegExp: /^[a-z]+$/i
    6.    Password:
    7.       NotEmpty: true
    8.       MinLength: 3
    9.       PasswordStrength: true
    10.    Confirm:
    11.       NotEmpty: true
    12.       Equals: Password
    13.    Email:
    14.       NotEmpty: true
    15.       ValidEmail: true
    Если какое-то из полей — неправильное, то должна вывестись ошибка, если все правильно — юзер должен быть зареген. При том, если неправильно и Confirm и Email, то должны вывестись две ошибки. Можешь показать пример?
     
  9. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    ты для полей правила пишешь, в результате у тебя дубликаты,
    я предлогаю поля для правил
    ну вот как бы я сделал
    PHP:
    1. <?
    2. Validator::Run($_POST);
    3.  
    4. Validator_Body::NotEmpty(array("nickname","password","confirm","email"),"Поля тра та та не должны быть пустыми");
    5. Validator_Body::LengthLimit(4,16,array("nickname"),"ошибка");
    6. Validator_Body::minLength(3,array("password"),/*...*/);
    7. // некоторые методы не понял что значат, но суть думаю понятна
    8.  
    9. if(!$err=Validator::getErrors()){
    10.    /* is valid */
    11. }else{
    12.    /* errros */
    13. }
    14.  
    15. ?>
     
  10. kostyl

    kostyl Guest

    Не понятно, а что мешает написать так:
    PHP:
    1.  
    2. <?php
    3. Validator::Run($_POST); // Массив с которым работаем по дефолту
    4.  
    5.  /*...*/
    6.  
    7.  /* Для небольших форм, можно делать так*/
    8.  if(Validator::NotEmpty(array("key1","key2"))) {} else { print "error"; }
    9.  if(Validator::NotEmpty(array("key1","key2"),null,$myArray)) {} else { print "error"; } // со своим массивом
    10.  
    11.  /*Для больших*/
    12.  
    13.  Validator::NotEmpty(array(/*...*/),"Ошибка тра та та");
    14.  Validator::maxLength(30,array(/*...*/),"Ошибка тра та та");
    15.  
    16.  if(!$errors=Validator::getErrors()){
    17.  }else{
    18.  
    Сам класс будет больше чтоли? Так же работаешь просто с одним объектом и всё. Не надо помнить что ошибки не в Validator_Body а в Validator. На Run очищаем предыдущие и делов то...
     
  11. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    преимущество как мне кажется в простоте
     
  12. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    а как новый функционал включать?
     
  13. kostyl

    kostyl Guest

    Mr.M.I.T.
    а я раздуплил идею твою про
    мне нравиться!!!
     
  14. kostyl

    kostyl Guest

    блин вечно этот мягкий знак...
     
  15. kostyl

    kostyl Guest

    но вот она не намного сократит если для каждого поля разные условия, хотя условия можно тоже в массив запечатать и как говорит TheShock тоже не пойму как из:
    PHP:
    1. <?php
    2. Validator_Body::NotEmpty(array("nickname","password","confirm","email"),"Поля тра та та не должны быть пустыми");
    3.  
    пользователь поймет что nickname не пустой и email не пустой, ну или ты как поймешь что именно их он не заполнил?
     
  16. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    это проблема из-за которой я начал говорить о неудобности валидаторов вцелом
    для маленьких форм я предложил делать так
    PHP:
    1. <?
    2. if(Validator_Body::NotEmpty(array("nickname","password","confirm","email"))) {} else {}
    это возврат назад, это ещё больше неудобно, проверено =)
    это будет заботой буфера, первое что на ум приходит
    PHP:
    1. <?php
    2.  Validator_Body::NotEmpty(array("nickname","password","confirm","email"),"Поле {name} не должны быть пустыми");
     
  17. kostyl

    kostyl Guest

    Не увидел
    А какой новый, их можно на пальцах пересчитать. В принципе я думаю, что регулярные выражения обрабатывают много чего: notEmpty и maxLength можно заменить одной регуляркой:
    PHP:
    1.  
    2. //Как в моем случае
    3. <?php
    4. define('USER_LOGIN_MINLENGTH', 2);
    5. define('USER_LOGIN_MAXLENGTH', 30);
    6. define('USER_LOGIN_MATCH', '/^[^\t]{' . USER_LOGIN_MINLENGTH . ',' . USER_LOGIN_MAXLENGTH . '}$/iu');
    7.  
    А насчет ошибок - ну что там надо, выдать их в массиве, ну вывести как нибудь еще. Так что я не особо думаю что буфер ошибок и валидация настолько велики чтобы разделять их. Ну может я еще не сильно с этим сталкивался так, чтобы меня это напрягло...
     
  18. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    разделил я как раз чтобы легко включать новый функционал, какой хз какой, народ на этом помешан =)
    регулярки зло, хотя и вкусное

    цель соб-но максимально упростить реализацию, работу функционала, со всеми вытекающими
     
  19. kostyl

    kostyl Guest

    ну тогда я соглашусь, только с таким изменением:
    PHP:
    1.  
    2. <?php
    3.  Validator_Body::Run($_POST);
    4. //.......
    5.  
     
  20. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Последнее время меня терзает следующая штука - вот есть у меня модули. В модуле может обрабатыватся более одной сущьности как таковой. Т.е. скажем у меня есть модуль Events, у каждого события есть комменты. Хочется один раз настроить всё и что бы оно само заботилось о валидации. Что-то типа модели данных. Однако как привнести это в реальную жизнь, где на каждую сущьность не нужно плодить отдельный класс, точнее даже на каждую таблицу и припихивать грёбанный ActiveRecord или ещё что-нить подобное - не знаю...

    Использование Validator:: по 3-4 раза в одном модуле (в разных методах) уже заябывает. Хочется более централизовано что-ли...
     
  21. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    Psih
    а комменты почему не отдельный модуль?
    kostyl
    хорошое дополнение
     
  22. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Ты же все же не ради правил валидатора работаешь....
    А ради полей. Поэтому разрывать поле по разным проверкам - не всегда есть хорошо.
     
  23. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    Simpliest
    но копипастить та проверки ещё хуже, не?
     
  24. kostyl

    kostyl Guest

    Psih
    ну это уже более широкий вопрос... А как ты смотришь на то чтобы половину валидаций отсеивать на уровне правил метаданных в таблице. Пришел логин больше поля - нече не сохранилось - ошибка.
    Кстати а что ты имеешь в виду с актив рекородом - типа какие данные пришли такой и объект будет. Один хрен это всё где то описывать надо, и актив рекорд - как бы напрашивается сам собой.
     
  25. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    хуже