[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Класс валидации данных
Страницы: 1, 2, 3
Zuenf
Возможно даже велосипед.
Писалось по идее CodeIgnite'ерского класса form_validation.
Изменения:
  • обработка любых данных, а не только пришедших по GET или POST
  • передача нескольких параметров для правила
  • возможность использовать как правила любую функцию или метод

Сам класс

class Validation
{
protected $rules; //переданные правила
protected $fields; //обрабатываемый массив данных
protected $validated; //обработанные поля

public $errors;

function __construct(){}

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

foreach($fields as $name => $value)
$this->validate_field($name);

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

protected function validate_field($name)
{
//если для данного поля есть правила и оно еще не было обработано
if(!in_array($name, $this->validated) && isset($this->rules[$name])){
$rules = explode('|', $this->rules[$name]);

foreach($rules as $key => $rule){
$parsed_rule = $this->parse_rule($rule, $name);

$result = call_user_func_array($parsed_rule['func'], $parsed_rule['params']);

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

$this->validated[] = $name; //поле обработанно
}

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

//тут самый страх
protected function parse_rule($rule, $self)
{
$params = array($this->fields[$self]); //запихиваем в параметры значение текущего поля для функций с одним параметром типа trim

//если правило с параметрами

if(preg_match("/(.*?)\((.*)\)/", $rule, $match)){
$rule = explode('->', $match[1]);
if(count($rule) == 1) $rule = $rule[0];

//разделяем параметры по запятым
$params = array_map('trim', str_getcsv($match[2]));

//ищем специальные параметры типа {name}, где name имя поля из массива данных,
//предварительно обработанное значение которого вставляется вместо {name}
//исключение {self} = значение текущего поля

$special_params = preg_grep("/^\{.+\}$/", $params);
if(count($special_params)){
$has_self = false;
foreach($special_params as $key => $field_name){
$value = $field_name = trim($field_name);
$field_name = substr($field_name, 1, -1);

if($field_name != $self && isset($this->fields[$field_name]))
//обрабатываем поле вне очереди
$value = $this->validate_field($field_name, $this->fields[$field_name]);
elseif($field_name == 'self' || $field_name == $self){
$value = $this->fields[$self];
$has_self = true;
}

$params[$key] = $value;
}
//если значение текущего поля нигде в параметрах не использовалось добавляем в начало параметров
if(!$has_self) array_unshift($params, $this->fields[$self]);
}else array_unshift($params, $this->fields[$self]);
}

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


Пример
function min_val($value, $limit){
return $value >= $limit;
}

function match($value, $match){
return $value === $match;
}

$data = array(
'name' => ' Asya',
'name_conf' => 'Vasya',
'pay' => 100
);

$valid = new Validation();

$rules = array(
'name' => 'trim|str_replace("A","Va",{self})|match({name_conf})',
'pay' => 'min_val(15)'
);

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


Посмотреть как работает и протестировать можно здесь.
Быстрый ответ:

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