Простой PHP валидатор
Октябрь 6, 2015
Однажды, один мой знакомый спросил меня, как
велосипедиста, как
бы я реализовал простую валидацию данных.
Ну если там несколько полей, то можно делать проверку через empty
или isset
:
if (empty($_POST['name'])) {
die('Поле "имя" не введено');
}
if (
empty($_POST['password']) ||
empty($_POST['password_confirm'])
) {
die('Поле "пароль" не введено');
}
А если нужна более сложная валидация данных то тут необойтись без написание простой маленькой библиотеки для валидации данных. Встречайте «Валидатор 2000»:
/**
* Валидатор 2000
*
* @author volter9
*/
/**
* @param array $data
* @param array $rules
* @return array
*/
function validate (array $data, array $rules) {
$errors = [];
foreach ($rules as $key => $rule) {
$error = validate_field($data[$key], parse_rule($rule), $data);
if ($error) {
$errors[$key] = $error;
}
}
return $errors;
}
/**
* @param mixed $value
* @param array $rule
* @param arary $data
* @return array
*/
function validate_field ($value, array $rule, array $data = []) {
$errors = [];
foreach ($rule as $validator => $args) {
$vargs = array_merge([$value, $data], $args);
if (!call_user_func_array($validator, $vargs)) {
$errors[$validator] = $args;
}
}
return $errors;
}
/**
* @param string $rule
* @return array
*/
function parse_rule ($rule) {
$rule = !$rule ? [] : $rule;
if (is_array($rule)) {
return $rule;
}
$result = [];
$rules = explode('|', $rule);
foreach ($rules as $rule) {
$frags = explode(':', $rule);
$name = $frags[0];
$args = isset($frags[1]) ? explode(',', $frags[1]) : [];
$result[$name] = $args;
}
return $result;
}
Как все это работает
Чтобы провести валидацию данных нужно воспользоваться функцией validate
.
Функция validate
берет два аргумента: ассоциативный массив с данными и
ассоциативный массив с правилами для этих данных.
Массив данных может содержать в себе все что угодно. Числа, строки, подмассивы, и т.д.
Массив с правилами должен содержать в себе пару ключ-значение, где ключ это название поля в массиве данных, а значение может быть либо форматированной строкой (упрощенную запись) в виде:
имя_валидатора|второй_валидатор:с одним аргументом|третий_валидатор:с двумя аргументами,2
Или же значение может быть массивом из ключей-значений где ключ это название валидатора, а значение это массив с аргументами которые нужно передать в валидатор (эти значения могут быть чем угодно). Это обычная запись правил для валидации.
Пример упрощенной и обычной записи правил.
$rules = [
/* Упрощенная запись */
'name' => 'required|confirm:password_confirm',
/* Обычная запись */
'password' => [
'required' => [],
'confirm' => ['password_confirm']
]
];
Можно использовать оба формата в функции validate
.
Когда функция validate
получает массив правил, она сначала приводит правила
в обычную запись с помощью функции parse_rule
(массив с аргументами).
После обработки правила во время каждой итерации данных, функция validate
проводит
валидацию каждого поля с помощью функции validate_field
передавая внутрь значение,
обработанные правила и массив с данными.
Алгоритм функции validate_field
очень прост. Эта функция получает три аргумента:
значение из массива с данных, правила в обычной форме и входной массив данных
(необязательный аргумент).
Эта функция проходится по всем правилам и вызывает валидаторы на переданном значение,
если значение не проходит валидатор то функция собирает аргументы от валидатора
в массив с ошибками, и возвращает массив с ошибками после окончания итерации.
На этом все об алгоритме, теперь немного о валидаторах.
Валидаторы
Для массива правил нужно обозначить валидатор для каждой поля (в виде ключа). Валидатор это простая пользовательская функция которая должна возвращать булевое значение. По умолчанию, в эту функцию поступает два параметра: значение поля и массив данных. Все аргументы которые были переданны в правила идут после этих два аргументов.
Пример валидатора:
function required ($value) {
return !empty($value);
}
И пример валидатора с дополнительными аргументами:
function confirm ($value, $array, $field) {
return isset($array[$field])
&& (string)$value === (string)$array[$field];
}
Для валидатора выше, нужно передать один аргумент в списке правил для поля:
// Упрощенная запись
'confirm:password_confirm'
// Обычная запись
[
'confirm' => ['password_confirm']
]
Пример использование библиотеки
Пример использования библиотеки:
/** Подключаем валидатор 2000 */
require 'validator.php';
/** Валидаторы */
function required ($value) {
return !!$value;
}
function confirm ($value, $array, $field) {
return isset($array[$field])
&& (string)$value === (string)$array[$field];
}
/**
* $rules - правила для валидации
* $pass_data - данные которые пройдут валидацию
* $fail_data - данные которые не пройдут валидацию
*/
$rules = [
'name' => 'required',
'password' => 'required|confirm:password_confirm'
];
$pass_data = [
'name' => 'Вася Пупкин',
'password' => '123456',
'password_confirm' => '123456'
];
$fail_data = [
'name' => '',
'password' => '123456',
'password_confirm' => '123'
];
if (!validate($pass_data, $rules)) {
echo 'Валидация прошла';
}
$errors = validate($fail_data, $rules);
if ($errors) {
echo 'Произошла ошибка:';
var_dump($errors);
}
Также данная библиотека доступна на GitHub Gist. Лицензия MIT.
- PHP
- валидация KISS YAGNI минимализм велосипед
Комментарии