Валидация
Composer предлагает множество валидаторов, которые можно использовать прямо из коробки, например:
top-think/think-validate
respect/validation
Валидация top-think/think-validate
Описание
Официальный валидатор ThinkPHP
Адрес проекта
https://github.com/top-think/think-validate
Установка
composer require topthink/think-validate
Быстрый старт
Создайте файл app/index/validate/User.php
<?php
namespace app\index\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
'name' => 'require|max:25',
'age' => 'number|between:1,120',
'email' => 'email',
];
protected $message = [
'name.require' => 'Имя обязательно',
'name.max' => 'Имя не должно превышать 25 символов',
'age.number' => 'Возраст должен быть числом',
'age.between' => 'Возраст должен быть между 1 и 120',
'email' => 'Неверный формат электронной почты',
];
}
Использование
$data = [
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com',
];
$validate = new \app\index\validate\User;
if (!$validate->check($data)) {
var_dump($validate->getError());
}
Внимание
В webman не поддерживается методValidate::rule()
из think-validate.
Валидация workerman/validation
Описание
Проект является китайской версией https://github.com/Respect/Validation
Адрес проекта
https://github.com/walkor/validation
Установка
composer require workerman/validation
Быстрый старт
<?php
namespace app\controller;
use support\Request;
use Respect\Validation\Validator as v;
use support\Db;
class IndexController
{
public function index(Request $request)
{
$data = v::input($request->post(), [
'nickname' => v::length(1, 64)->setName('Ник'),
'username' => v::alnum()->length(5, 64)->setName('Имя пользователя'),
'password' => v::length(5, 64)->setName('Пароль')
]);
Db::table('user')->insert($data);
return json(['code' => 0, 'msg' => 'ok']);
}
}
Доступ через jQuery
$.ajax({
url : 'http://127.0.0.1:8787',
type : "post",
dataType:'json',
data : {nickname:'Том', username:'tom cat', password: '123456'}
});
Результат:
{"code":500,"msg":"Имя пользователя должно содержать только буквы (a-z) и цифры (0-9)"}
Объяснение:
v::input(array $input, array $rules)
используется для валидации и сбора данных. Если валидация данных не прошла, выбрасывается исключение Respect\Validation\Exceptions\ValidationException
; если валидация успешна, возвращаются проверенные данные (массив).
Если бизнес-логика не перехватила исключение валидации, фреймворк webman автоматически перехватит его и вернет данные в формате JSON (например, {"code":500, "msg":"xxx"}
) либо обычную страницу с ошибкой, в зависимости от заголовков HTTP-запроса. Если формат ответа не соответствует требованиям бизнес-логики, разработчик может самостоятельно перехватить исключение ValidationException
и вернуть необходимые данные, как в следующем примере:
<?php
namespace app\controller;
use support\Request;
use Respect\Validation\Validator as v;
use Respect\Validation\Exceptions\ValidationException;
class IndexController
{
public function index(Request $request)
{
try {
$data = v::input($request->post(), [
'username' => v::alnum()->length(5, 64)->setName('Имя пользователя'),
'password' => v::length(5, 64)->setName('Пароль')
]);
} catch (ValidationException $e) {
return json(['code' => 500, 'msg' => $e->getMessage()]);
}
return json(['code' => 0, 'msg' => 'ok', 'data' => $data]);
}
}
Руководство по функциональности Validator
use Respect\Validation\Validator as v;
// Валидация с одним правилом
$number = 123;
v::numericVal()->validate($number); // true
// Множественная валидация с цепочкой правил
$usernameValidator = v::alnum()->noWhitespace()->length(1, 15);
$usernameValidator->validate('alganet'); // true
// Получение первой причины неудачной валидации
try {
$usernameValidator->setName('Имя пользователя')->check('alg anet');
} catch (ValidationException $exception) {
echo $exception->getMessage(); // Имя пользователя должно содержать только буквы (a-z) и цифры (0-9)
}
// Получение всех причин неудачной валидации
try {
$usernameValidator->setName('Имя пользователя')->assert('alg anet');
} catch (ValidationException $exception) {
echo $exception->getFullMessage();
// Будет напечатано
// - Имя пользователя должно соответствовать следующим правилам
// - Имя пользователя должно содержать только буквы (a-z) и цифры (0-9)
// - Имя пользователя не может содержать пробелы
var_export($exception->getMessages());
// Будет напечатано
// array (
// 'alnum' => 'Имя пользователя должно содержать только буквы (a-z) и цифры (0-9)',
// 'noWhitespace' => 'Имя пользователя не может содержать пробелы',
// )
}
// Пользовательские сообщения об ошибках
try {
$usernameValidator->setName('Имя пользователя')->assert('alg anet');
} catch (ValidationException $exception) {
var_export($exception->getMessages([
'alnum' => 'Имя пользователя может содержать только буквы и цифры',
'noWhitespace' => 'Имя пользователя не должно иметь пробелы',
'length' => 'length соответствует правилам, поэтому это сообщение не будет отображаться'
]));
// Будет напечатано
// array(
// 'alnum' => 'Имя пользователя может содержать только буквы и цифры',
// 'noWhitespace' => 'Имя пользователя не должно иметь пробелы'
// )
}
// Валидация объекта
$user = new stdClass;
$user->name = 'Александр';
$user->birthdate = '1987-07-01';
$userValidator = v::attribute('name', v::stringType()->length(1, 32))
->attribute('birthdate', v::date()->minAge(18));
$userValidator->validate($user); // true
// Валидация массива
$data = [
'parentKey' => [
'field1' => 'value1',
'field2' => 'value2',
'field3' => true,
]
];
v::key(
'parentKey',
v::key('field1', v::stringType())
->key('field2', v::stringType())
->key('field3', v::boolType())
)
->assert($data); // также можно использовать check() или validate()
// Условная валидация
v::alpha()->validate(''); // false
v::alpha()->validate(null); // false
v::optional(v::alpha())->validate(''); // true
v::optional(v::alpha())->validate(null); // true
// Отрицательные правила
v::not(v::intVal())->validate(10); // false
Различия между методами validate()
, check()
, assert()
validate()
возвращает логическое значение и не выбрасывает исключений.
check()
выбрасывает исключение при неудаче валидации; можно получить первую причину неудачи через $exception->getMessage()
.
assert()
выбрасывает исключение при неудаче валидации; можно получить все причины неудачи через $exception->getFullMessage()
.
Список распространённых правил валидации
Alnum()
только буквы и цифры
Alpha()
только буквы
ArrayType()
массив
Between(mixed $minimum, mixed $maximum)
проверяет, находится ли ввод в пределах двух значений.
BoolType()
проверяет, является ли ввод булевым значением
Contains(mixed $expectedValue)
проверяет, содержит ли ввод определенные значения
ContainsAny(array $needles)
проверяет, содержит ли ввод хотя бы одно из определенных значений
Digit()
проверяет, состоит ли ввод только из цифр
Domain()
проверяет, является ли введенное значение действительным доменом
Email()
проверяет, является ли введенное значение действительным адресом электронной почты
Extension(string $extension)
проверяет расширение
FloatType()
проверяет, является ли введенное значение действительным числом с плавающей точкой
IntType()
проверяет, является ли ввод целым числом
Ip()
проверяет, является ли ввод адресом IPv4 или IPv6
Json()
проверяет, является ли ввод данными JSON
Length(int $min, int $max)
проверяет, находится ли длина в пределах заданного диапазона
LessThan(mixed $compareTo)
проверяет, меньше ли длина заданного значения
Lowercase()
проверяет, состоит ли ввод из строчных букв
MacAddress()
проверяет, является ли введенное значение MAC-адресом
NotEmpty()
проверяет, не пусто ли значение
NullType()
проверяет, является ли значение null
Number()
проверяет, является ли ввод числом
ObjectType()
проверяет, является ли ввод объектом
StringType()
проверяет, является ли ввод строкой
Url()
проверяет, является ли ввод URL
Больше правил валидации можно найти по адресу https://respect-validation.readthedocs.io/en/2.0/list-of-rules/