Возможность создавать произвольные правила с помощью create_function Код (PHP): <?php /* (c)2010 Vasiliy B. Shpilchin */ class formValidator { private $fields = array(); private $rules = array(); public function __construct($name, $method = 'get') { $this->fields = strtolower($method) == 'post' ? $_POST[$name] : $_GET[$name]; } public function setRule($name, $source) { $this->rules[$name] = $source; } public function compile() { $result = array(); foreach ($this->fields as $name => $value) { $fn = create_function('$f', 'return '.$this->rules[$name].';'); $result[$name] = (bool)$fn($value); } return $result; } } $_POST['login']['email'] = 'vasyaemail@mail.ru'; $_POST['login']['password'] = '123йцу'; $validator = new formValidator('login', 'post'); $validator->setRule('email', 'filter_var($f, FILTER_VALIDATE_EMAIL)'); $validator->setRule('password', '$f == preg_replace ("/[^\w\d\s_]*/","",$f)'); var_dump($validator->compile()); В продолжении идеи - паковать правила в отдельный объекты, привязывать объекты к формам...
Можно ускорить работу 10 раз, если создавать функцию при добавлении правила Код (PHP): $this->rules[$name] = create_function('$f', 'return '.$source.';'); если одинаковые правила используются для разных полей. Код (PHP): $result[$name] = (bool)$this->rules[$name]($value);
а можно ускорить дальнейшую обработку глазом в будущем, использовав php5.3 и лямбда функции $this->rules[$name] = function($f) { return $source;};
кстати, вот это не совсем валидация, а скорее эскейп PHP: $validator->setRule('password', '$f == preg_replace ("/[^\w\d\s_]*/","",$f)');
А мне нравиться как сделано в Yii. Идея проста до безобразия, но сволочь как элегантно. Советую посмотреть (лямбда-функции тоже поддерживаются кстати)
Вот еще один пример реализации. Довольно специфическое решение, недостаток, по крайней мере для меня в том, что для сложных правил надо делать некую структуру наследования. Ну вообщем может кому для какой-то задачи как раз подойдёт.
А как на счет вот такого интерфейса для валидатора? PHP: <? $loginRules = array( 'nicklen' => 'in_array(strlen($f), range(3,20))', 'nickchr' => '$f == preg_replace ("/[^\w\d\s_]*/","",$f)', 'pwdlen' => 'in_array(strlen($f), range(4,20))' ); Spirit_Form::importRules($loginRules); // типа поля должны быть с именами ln[nick], ln[password] Spirit_Form::makeForm('ln', 'POST'); Spirit_Form::setRelation('ln', 'nick', 'nicklen'); Spirit_Form::setRelation('ln', 'nick', 'nickchr'); Spirit_Form::setRelation('ln', 'password', 'pwdlen'); $lnValid = Spirit_Form::isValid('ln'); // bool $validResult = Spirit_Form::getValidationResult('ln'); // массив типа nick=>true
[vs] а сами сам текст ошибок где брать? или отдельно создаешь массив и во время перебора validResult, если ошибка подставляешь?
Padaboo Тексты ошибок сразу есть в шаблоне, просто скрыты свойством с помощью CSS. По результатам валидации становятся видимыми. Короче не связаны с валидатором.
твоя задача максимально утончено избавитсья от кучи if...else -> error я бы делал это так PHP: <?php if(!empty($_POST['done'])){ $errors=APP_Models_Auth::ValidateALL($_POST); if(!$errors){ /*....*/ }else{ print_r($errors); } } ?> а уж как ты в модели сделает, да как хочешь.[/code]
В зенде так и есть - делается форма с набором валидаторов, а потом PHP: <?php $form = new Form_User_Register(); $data = $this->getRequest()->getPost(); if ($this->getRequest()->isPost() && $$form->isValid($data)) { $form->save($data); } else { $this->view->errors = $form->getErrors(); } $form->populate($data) ну типа такого...