[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Класс валидации данных
Страницы: 1, 2, 3
stump
Цитата (chee @ 31.01.2015 - 19:27)
stump, за вас в оформлении кода уже все решили, вам осталось только использовать, гулите: PSR-0, PSR-2

Я нагуглил что некоторые люди предложили принять такие рекомендации как стандарты. а что все решили также никак не могу нагуглить.

_____________
Трус не играет в хокей
chee
stump, ок, рекомендации как стандарты, ок решили не все, а разработчики ведущих программных решений на php. Твоё дело принимать их или нет, основной посыл был в том, что за тебя все уже придумали, не нужно изобретать стиль форматирования кода. И вообще это оффтоп.

_____________
Люди, имеющие низкий уровень квалификации, делают ошибочные выводы, принимают неудачные решения и при этом неспособны осознавать свои ошибки в силу низкого уровня своей квалификации
Zuenf
Апдатe:
  • возможность установки обработчиков для правил с помощью метода Validator::setHandler($name, Closure $handler)
  • возможность задавать правила как массивом, так и строкой
  • "разделении обязоностей в коде" © chee
  • фикс бага бесконечного инклуда одним полем другого и обратно при задании соответствующих правил.
Класс:

class Validator
{
protected $handlersRules; //обрабочики правил
protected $rules; //переданные правила
protected $fields; //обрабатываемый массив данных
protected $process; //обработанные поля
protected $errors;

function __construct()
{
$this->handlersRules = array();
}

public function run(array $rules, array $fields)
{
$this->rules = $rules;
$this->fields = $fields;
$this->process = array();
$this->errors = array();

foreach ($rules as $name => $value) {
$this->processField($name);
}

return count($this->errors) ? false : $this->fields;
}

public function setHandler($name, Closure $handler)
{
$this->handlersRules[$name] = $handler;
}

public function getErrors()
{
return $this->errors;
}

protected function processField($fieldName)
{
//если для данного поля есть правила и оно еще не обрабатывалось
if(empty($this->process[$fieldName]) && isset($this->rules[$fieldName])){
$this->process[$fieldName] = true; //поле обрабатывается

$rules = $this->rules[$fieldName];

if (is_string($rules)) {
$rules = $this->parseRulesList($rules);
} elseif (!is_array($rules)) {
throw new Exception('Wrong rules format!');
}

foreach ($rules as $func => $params) {
$params = $this->mountSpecialParams($params, $fieldName);

$result = $this->performRule($func, $params);

//если функция обработки вернула boolean значит это функция проверки, иначе функция изменила значение
if (is_bool($result)) {
if ($result === false) {
$this->errors[$fieldName][$func] = $params;
}
}
else $this->fields[$fieldName] = $result;
}
}


return $this->fields[$fieldName];
}

//приводим строковые правила к соответствующему массиву
protected function parseRulesList($rules)
{
$rules = explode('|', $rules);
$parsedRules = array();
foreach ($rules as $key => $rule) {
$rule = $this->parseRule($rule);
$parsedRules[$rule['func']] = $rule['params'];
}

return $parsedRules;
}

protected function parseRule($rule)
{
$params = array();

if (preg_match("/(.*?)\((.*)\)/", $rule, $match)) {
$rule = $match[1];
$params = array_map('trim', str_getcsv($match[2]));
}

return array(
'func' => $rule,
'params' => $params
);
}

//выполняем правило либо из обработчика, либо глобальную функцию или метод
protected function performRule($name, $params)
{
if (isset($this->handlersRules[$name])) {
$func = $this->handlersRules[$name];
} else {
$func = explode('->', $name);
if(count($func) == 1){
$func = $name;
}

if(!is_callable($func)){
throw new Exception('There is no such handler!');
}
}


return call_user_func_array($func, $params);
}

//заменяем параметры вида {name}, на предварительно обработанное значение с соответствующим именем из массива данных
protected function mountSpecialParams($params, $self)
{
$specialParams = preg_grep("/^\{.+\}$/", $params);
$hasSelf = false;

foreach ($specialParams as $key => $param) {
$param = trim(substr($param, 1, -1));

if($param == 'self' || $param == $self){
$param = $self;
$hasSelf = true;
}

$params[$key] = $this->processField($param);
}

if (!$hasSelf) {
array_unshift($params, $this->processField($self));
}

return $params;
}
}

Пример:


$data = array(
'name' => ' Che Guevara ',
'password' => '123456',
'password_conf' => '123456'
);

$valid = new Validator();

$valid->setHandler('match', function($value, $match){
return $value === $match;
});

$valid->setHandler('str_range', function($str, $min, $max){
$length = strlen($str);
return $length >= $min && $length <= $max;
});


$rules = array(
'name' => 'trim|str_replace("Che Guevara", "Ernesto", {self})',
'password' => array(
'str_range' => array(6, 30),
'match' => array('{password_conf}'),
'md5' => array()
)
);


if ($result = $valid->run($rules, $data)) {
echo 'Валидация прошла успешно<br>';
echo 'Было:<br>';
echo '<pre>'.print_r($data,true).'</pre>';
echo 'Стало:<br>';
echo '<pre>'.print_r($result,true).'</pre>';
} else {
echo 'параметры не соответствуют правилам<br>';
echo 'Массив ошибок:<br>';
echo '<pre>'.print_r($valid->getErrors(),true).'</pre>';
}

Резултат:
Валидация прошла успешно
Было:
Array
(
[
name] => Che Guevara
[password] => 123456
[password_conf] => 123456
)
Стало:
Array
(
[
name] => Ernesto
[password] => e10adc3949ba59abbe56e057f20f883e
[password_conf] => 123456
)


Пример онлайн.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.