За последние 24 часа нас посетили 18176 программистов и 1684 робота. Сейчас ищет 1081 программист ...

Еще валидатор форм (идея/реализация)

Тема в разделе "Решения, алгоритмы", создана пользователем [vs], 15 сен 2010.

  1. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Возможность создавать произвольные правила с помощью create_function
    Код (PHP):
    1. <?php
    2. /* (c)2010 Vasiliy B. Shpilchin */
    3. class formValidator
    4. {
    5.     private $fields = array();
    6.     private $rules = array();
    7.     
    8.     public function  __construct($name, $method = 'get') {
    9.         $this->fields = strtolower($method) == 'post' ? $_POST[$name] : $_GET[$name];
    10.     }
    11.  
    12.     public function setRule($name, $source) {
    13.         $this->rules[$name] = $source;
    14.     }
    15.  
    16.     public function compile() {
    17.         $result = array();
    18.         foreach ($this->fields as $name => $value) {
    19.             $fn = create_function('$f', 'return '.$this->rules[$name].';');
    20.             $result[$name] = (bool)$fn($value);
    21.         }
    22.         return $result;
    23.     }
    24. }
    25.  
    26. $_POST['login']['email'] = 'vasyaemail@mail.ru';
    27. $_POST['login']['password'] = '123йцу';
    28.  
    29. $validator = new formValidator('login', 'post');
    30. $validator->setRule('email', 'filter_var($f, FILTER_VALIDATE_EMAIL)');
    31. $validator->setRule('password', '$f == preg_replace ("/[^\w\d\s_]*/","",$f)');
    32.  
    33. var_dump($validator->compile()); 
    В продолжении идеи - паковать правила в отдельный объекты, привязывать объекты к формам...
     
  2. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Можно ускорить работу 10 раз, если создавать функцию при добавлении правила
    Код (PHP):
    1. $this->rules[$name] = create_function('$f', 'return '.$source.';'); 
    если одинаковые правила используются для разных полей.
    Код (PHP):
    1. $result[$name] = (bool)$this->rules[$name]($value); 
     
  3. phpdude

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

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    а можно ускорить дальнейшую обработку глазом в будущем, использовав php5.3 и лямбда функции

    $this->rules[$name] = function($f) { return $source;};
     
  4. Mr.M.I.T.

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

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    а можно вообще не ипать мозг и сделать набор моделей со статическими методами
     
  5. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Mr.M.I.T.
    Модели для валидации форм? Это же никакого повторного использования.
     
  6. Mr.M.I.T.

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

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
  7. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Ты имел ввиду валидировать данные в моделях, без специфического валидатора форм?
     
  8. Mr.M.I.T.

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

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    нет. валидирует контроллер используя нужную модель, а не специфический нафиг не нужный валидатор =)
     
  9. Mr.M.I.T.

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

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    кстати, вот это не совсем валидация, а скорее эскейп
    PHP:
    1.  $validator->setRule('password', '$f == preg_replace ("/[^\w\d\s_]*/","",$f)');
     
  10. Psih

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

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    А мне нравиться как сделано в Yii. Идея проста до безобразия, но сволочь как элегантно. Советую посмотреть (лямбда-функции тоже поддерживаются кстати) :)
     
  11. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Нет, там знак сравнения а не равенства

    Psih
    А где он там?
     
  12. Mr.M.I.T.

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

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    а ну да. тогда это просто говнокод =)
     
  13. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    Вот еще один пример реализации. Довольно специфическое решение, недостаток, по крайней мере для меня в том, что для сложных правил надо делать некую структуру наследования.
    Ну вообщем может кому для какой-то задачи как раз подойдёт.
     
  14. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    А как на счет вот такого интерфейса для валидатора?
    PHP:
    1. <?
    2.             $loginRules = array(
    3.                 'nicklen' => 'in_array(strlen($f), range(3,20))',
    4.                 'nickchr' => '$f == preg_replace ("/[^\w\d\s_]*/","",$f)',
    5.                 'pwdlen' => 'in_array(strlen($f), range(4,20))'
    6.             );
    7.             Spirit_Form::importRules($loginRules);
    8.             // типа поля должны быть с именами ln[nick], ln[password]
    9.             Spirit_Form::makeForm('ln', 'POST');
    10.             Spirit_Form::setRelation('ln', 'nick', 'nicklen');
    11.             Spirit_Form::setRelation('ln', 'nick', 'nickchr');
    12.             Spirit_Form::setRelation('ln', 'password', 'pwdlen');
    13.             $lnValid = Spirit_Form::isValid('ln'); // bool
    14.             $validResult = Spirit_Form::getValidationResult('ln'); // массив типа nick=>true
    15.  
     
  15. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    [vs]
    а сами сам текст ошибок где брать? или отдельно создаешь массив и во время перебора validResult, если ошибка подставляешь?
     
  16. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Padaboo
    Тексты ошибок сразу есть в шаблоне, просто скрыты свойством с помощью CSS. По результатам валидации становятся видимыми.
    Короче не связаны с валидатором.
     
  17. Mr.M.I.T.

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

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    твоя задача максимально утончено избавитсья от кучи if...else -> error
    я бы делал это так
    PHP:
    1. <?php
    2. if(!empty($_POST['done'])){
    3.     $errors=APP_Models_Auth::ValidateALL($_POST);
    4.     if(!$errors){
    5.       /*....*/
    6.     }else{
    7.       print_r($errors);
    8.     }
    9. }
    10. ?>
    а уж как ты в модели сделает, да как хочешь.[/code]
     
  18. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    В зенде так и есть - делается форма с набором валидаторов, а потом
    PHP:
    1. <?php
    2. $form = new Form_User_Register();
    3. $data = $this->getRequest()->getPost();
    4. if ($this->getRequest()->isPost() && $$form->isValid($data)) {
    5.   $form->save($data);
    6. }
    7. else {
    8.   $this->view->errors = $form->getErrors();
    9. }
    10.  
    11. $form->populate($data)
    ну типа такого...