gzhegow / validator
1.0.0
2025-04-24 20:25 UTC
Requires
- php: ^7.3|^8.0
- gzhegow/lib: ~1.0
Suggests
- ext-json: *
- ext-mbstring: *
README
Валидатор произвольных массивов: быстрый, умный, простой, легкий.
Сама идея бралась из illuminate\validation
, который, кхм - медленный, глупый, сложный, тяжелый.
- с поддержкой большинства правил laravel валидатора (прочитать документацию), но и с многими другими
- с отключенным приведением пустых строк к NULL, но возможностью удалить все пустые строки из данных через ->modeWeb()
- с возможностью удалить все NULL из данных через ->modeApi(), чтобы сделать поддержку например
{N}
, если в API интерпретировать NULL как "не трогать", а{N}
как "очистить" - с механизмом фильтрации полей, применяемым до валидации
- с механизмом перевода на другой язык, реализуйте произвольный переводчик
- с возможностью получить
[ rules ][ errors ][ messages ]
в виде dot-нотации - с возможностью маппить на массив или объект данные из
[ data ][ dataValidated ]
и[ all ][ valid ][ invalid ][ validated ]
- с возможностью полной кастомизации как текстовой формы валидации, так и объектной
- с возможностью соединять несколько валидаций в одну
- с возможностью запускать единожды созданный валидатор несколько раз, добавляя в него правила и данные
Установить
composer require gzhegow/validator
Запустить тесты
php test.php
Примеры и тесты
<?php require_once __DIR__ . '/../vendor/autoload.php'; // > настраиваем PHP ini_set('memory_limit', '32M'); // > настраиваем обработку ошибок (new \Gzhegow\Lib\Exception\ErrorHandler()) ->useErrorReporting() ->useErrorHandler() ->useExceptionHandler() ; // > объявляем несколько функция для тестирования $ffn = new class { function root() : string { return realpath(__DIR__ . '/..'); } function value_array_multiline($value, ?int $maxLevel = null, array $options = []) : string { return \Gzhegow\Lib\Lib::debug()->value_array_multiline($value, $maxLevel, $options); } function values($separator = null, ...$values) : string { return \Gzhegow\Lib\Lib::debug()->values([], $separator, ...$values); } function print(...$values) : void { echo $this->values(' | ', ...$values) . PHP_EOL; } function print_array_multiline($value, ?int $maxLevel = null, array $options = []) : void { echo $this->value_array_multiline($value, $maxLevel, $options) . PHP_EOL; } function assert_stdout( \Closure $fn, array $fnArgs = [], string $expectedStdout = null ) : void { $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1); \Gzhegow\Lib\Lib::test()->assertStdout( $trace, $fn, $fnArgs, $expectedStdout ); } }; // > создаем enum-ы для тестирования правила InEnum (только для PHP >8.1.0) if (PHP_VERSION_ID >= 80100) { require_once $ffn->root() . '/tests/src/Enum/HelloWorldEnum.php'; require_once $ffn->root() . '/tests/src/Enum/HelloWorldBackedEnum.php'; } // >>> ЗАПУСКАЕМ! // > сначала всегда фабрика (она также создает зарегистрированные Rule, т.е. можно подключить IoC контейнер) $factory = new \Gzhegow\Validator\ValidatorFactory(); // > создаем процессор для вызова фильтров, поскольку отдельной сущности фильтр не предусмотрено, это может быть callable $processor = new \Gzhegow\Validator\Processor\ValidatorProcessor( $factory ); // > создаем переводчик, который преобразует ошибки и исключения валидатора на требуемый язык, подставляет параметры или меняет название атрибутов // > по-умолчанию он просто выводит сообщение, которое возвращено из правила // > это правильное место, чтобы внедрить свой переводчик на разные языки $translator = new \Gzhegow\Validator\Translator\ValidatorPassTranslator(); // > создаем регистр правил, где правила проходят регистрацию // > если вы задаете правила используя объекты и фасады - их можно не регистрировать // > регистрация нужна ТОЛЬКО для разбора полностью текстовых правил // > текстовая форма валидаций удобно отправляется на фронтенд при работе в команде // > - в текстовой форме записи легко ошибится // > - если ваши правила могут сменить названия, то тексты останутся нетронутыми // // > `present|string|size_min:1` // > vs // > `[ Rule::present(), Rule::string(), Rule::size_min(1) ]` $registry = new \Gzhegow\Validator\RuleRegistry\RuleRegistry(); $registry->register(\Gzhegow\Validator\Rule\Kit\Rule::class); // > можно разрегистрировать некоторые правила, чтобы заменить своими // $registry->removeRules([ 'string' ]); // $registry->addRule(\Gzhegow\Validator\Rule\Kit\Type\StringRule::class); // > создаем фасад $validator = new \Gzhegow\Validator\ValidatorFacade( $factory, $processor, $translator, // $registry ); // > регистрируем фасад в статику для удобного доступа из закрытых контекстов \Gzhegow\Validator\Validator::setFacade($validator); // > ПРИМЕР со всеми правилами, которые идут в комплекте // // $validation = \Gzhegow\Validator\Validator::new(); // // (function ($validation) { // $validation->addData([ // 'blank' => null, // 'not_blank' => 0, // // // 'present' => null, // // 'not_present' => null, // // // '_present_any_a' => null, // // '_present_any_b' => null, // // 'present_any' => 0, // // 'presented_without_all' => 0, // // // '_present_pair_a' => null, // // '_present_pair_b' => null, // 'present_pair' => 0, // 'presented_with_one' => 0, // // // '_present_side_a' => null, // '_present_side_b' => null, // // 'present_side' => 0, // // 'presented_without_one' => 0, // // // '_present_set_a' => null, // '_present_set_b' => null, // 'present_set' => 0, // 'presented_with_all' => 0, // ]); // // $validation->addRules('blank', [ \Gzhegow\Validator\Rule\Kit\Rule::blank() ]); // $validation->addRules('not_blank', [ \Gzhegow\Validator\Rule\Kit\Rule::not_blank() ]); // // // $validation->addRules('present', [ \Gzhegow\Validator\Rule\Kit\Rule::present() ]); // $validation->addRules('not_present', [ \Gzhegow\Validator\Rule\Kit\Rule::not_present() ]); // // // $validation->addRules('present_any', [ \Gzhegow\Validator\Rule\Kit\Rule::present_any([ [ '_present_any_a', '_present_any_b' ] ]) ]); // $validation->addRules('presented_without_all', [ \Gzhegow\Validator\Rule\Kit\Rule::presented_without_all([ [ '_present_any_a', '_present_any_b' ] ]) ]); // // // $validation->addRules('present_pair', [ \Gzhegow\Validator\Rule\Kit\Rule::present_pair([ [ '_present_pair_a', '_present_pair_b' ] ]) ]); // $validation->addRules('presented_with_one', [ \Gzhegow\Validator\Rule\Kit\Rule::presented_with_one([ [ '_present_pair_a', '_present_pair_b' ] ]) ]); // // // $validation->addRules('present_side', [ \Gzhegow\Validator\Rule\Kit\Rule::present_side([ [ '_present_side_a', '_present_side_b' ] ]) ]); // $validation->addRules('presented_without_one', [ \Gzhegow\Validator\Rule\Kit\Rule::presented_without_one([ [ '_present_side_a', '_present_side_b' ] ]) ]); // // // $validation->addRules('present_set', [ \Gzhegow\Validator\Rule\Kit\Rule::present_set([ [ '_present_set_a', '_present_set_b' ] ]) ]); // $validation->addRules('presented_with_all', [ \Gzhegow\Validator\Rule\Kit\Rule::presented_with_all([ [ '_present_set_a', '_present_set_b' ] ]) ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'diff_all' => [ 1, 2, 3 ], // 'diff_any' => [ 1, 2, 3 ], // 'intersect_all' => [ 1, 2, 3 ], // 'intersect_any' => [ 1, 2, 3 ], // 'keys_diff_all' => [ 1 => true, 2 => true, 3 => true ], // 'keys_diff_any' => [ 1 => true, 2 => true, 3 => true ], // 'keys_intersect_all' => [ 1 => true, 2 => true, 3 => true ], // 'keys_intersect_any' => [ 1 => true, 2 => true, 3 => true ], // 'unique' => [ 'name1', 'Name1' ], // ]); // // $validation->addRules('diff_all', [ \Gzhegow\Validator\Rule\Kit\Rule::diff_all([ [ 4 ] ]) ]); // $validation->addRules('diff_any', [ \Gzhegow\Validator\Rule\Kit\Rule::diff_any([ [ 1, 2, 3, 4 ] ]) ]); // $validation->addRules('intersect_all', [ \Gzhegow\Validator\Rule\Kit\Rule::intersect_all([ [ 1, 2, 3 ] ]) ]); // $validation->addRules('intersect_any', [ \Gzhegow\Validator\Rule\Kit\Rule::intersect_any([ [ 1 ] ]) ]); // $validation->addRules('keys_diff_all', [ \Gzhegow\Validator\Rule\Kit\Rule::keys_diff_all([ [ 4 ] ]) ]); // $validation->addRules('keys_diff_any', [ \Gzhegow\Validator\Rule\Kit\Rule::keys_diff_any([ [ 1, 2, 3, 4 ] ]) ]); // $validation->addRules('keys_intersect_all', [ \Gzhegow\Validator\Rule\Kit\Rule::keys_intersect_all([ [ 1, 2, 3 ] ]) ]); // $validation->addRules('keys_intersect_any', [ \Gzhegow\Validator\Rule\Kit\Rule::keys_intersect_any([ [ 1 ] ]) ]); // $validation->addRules('unique', [ \Gzhegow\Validator\Rule\Kit\Rule::unique() ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'date_between' => new \DateTime('@5'), // 'date_inside' => new \DateTime('@5'), // 'date_eq' => new \DateTime('@5'), // 'date_neq' => new \DateTime('@5'), // 'date_gt' => new \DateTime('@5'), // 'date_lt' => new \DateTime('@5'), // 'date_max' => new \DateTime('@5'), // 'date_min' => new \DateTime('@5'), // // // '_date_field_0' => new \DateTime('@0'), // '_date_field_5' => new \DateTime('@5'), // '_date_field_10' => new \DateTime('@10'), // 'date_eq_field' => new \DateTime('@5'), // 'date_neq_field' => new \DateTime('@5'), // 'date_gt_field' => new \DateTime('@5'), // 'date_lt_field' => new \DateTime('@5'), // 'date_max_field' => new \DateTime('@5'), // 'date_min_field' => new \DateTime('@5'), // ]); // // $validation->addRules('date_between', [ \Gzhegow\Validator\Rule\Kit\Rule::date_between([ '@5', '@10' ]) ]); // $validation->addRules('date_inside', [ \Gzhegow\Validator\Rule\Kit\Rule::date_inside([ '@0', '@10' ]) ]); // $validation->addRules('date_eq', [ \Gzhegow\Validator\Rule\Kit\Rule::date_eq([ '@5' ]) ]); // $validation->addRules('date_neq', [ \Gzhegow\Validator\Rule\Kit\Rule::date_neq([ '@0' ]) ]); // $validation->addRules('date_gt', [ \Gzhegow\Validator\Rule\Kit\Rule::date_gt([ '@0' ]) ]); // $validation->addRules('date_lt', [ \Gzhegow\Validator\Rule\Kit\Rule::date_lt([ '@10' ]) ]); // $validation->addRules('date_max', [ \Gzhegow\Validator\Rule\Kit\Rule::date_max([ '@5' ]) ]); // $validation->addRules('date_min', [ \Gzhegow\Validator\Rule\Kit\Rule::date_min([ '@5' ]) ]); // // // $validation->addRules('date_eq_field', [ \Gzhegow\Validator\Rule\Kit\Rule::date_eq_field([ '_date_field_5' ]) ]); // $validation->addRules('date_neq_field', [ \Gzhegow\Validator\Rule\Kit\Rule::date_neq_field([ '_date_field_0' ]) ]); // $validation->addRules('date_gt_field', [ \Gzhegow\Validator\Rule\Kit\Rule::date_gt_field([ '_date_field_0' ]) ]); // $validation->addRules('date_lt_field', [ \Gzhegow\Validator\Rule\Kit\Rule::date_lt_field([ '_date_field_10' ]) ]); // $validation->addRules('date_max_field', [ \Gzhegow\Validator\Rule\Kit\Rule::date_max_field([ '_date_field_5' ]) ]); // $validation->addRules('date_min_field', [ \Gzhegow\Validator\Rule\Kit\Rule::date_min_field([ '_date_field_5' ]) ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'size_between' => [ 1, 1, 1 ], // 'size_min' => [ 1, 1, 1 ], // 'size_max' => [ 1, 1, 1 ], // 'size' => [ 1, 1, 1 ], // ]); // // $validation->addRules('size_between', [ \Gzhegow\Validator\Rule\Kit\Rule::size_between([ 3, 3 ]) ]); // $validation->addRules('size_min', [ \Gzhegow\Validator\Rule\Kit\Rule::size_min([ 3 ]) ]); // $validation->addRules('size_max', [ \Gzhegow\Validator\Rule\Kit\Rule::size_max([ 3 ]) ]); // $validation->addRules('size', [ \Gzhegow\Validator\Rule\Kit\Rule::size([ 3 ]) ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'between' => 'b', // 'inside' => 'b', // 'eq' => 'b', // 'neq' => 'b', // 'gt' => 'b', // 'lt' => 'b', // 'lte' => 'b', // 'gte' => 'b', // // // '_field_a' => 'a', // '_field_b' => 'b', // '_field_c' => 'c', // 'eq_field' => 'b', // 'neq_field' => 'b', // 'gt_field' => 'b', // 'lt_field' => 'b', // 'lte_field' => 'b', // 'gte_field' => 'b', // ]); // // $validation->addRules('between', [ \Gzhegow\Validator\Rule\Kit\Rule::between([ 'b', 'c' ]) ]); // $validation->addRules('inside', [ \Gzhegow\Validator\Rule\Kit\Rule::inside([ 'a', 'c' ]) ]); // $validation->addRules('eq', [ \Gzhegow\Validator\Rule\Kit\Rule::eq([ 'b' ]) ]); // $validation->addRules('neq', [ \Gzhegow\Validator\Rule\Kit\Rule::neq([ 'a' ]) ]); // $validation->addRules('gt', [ \Gzhegow\Validator\Rule\Kit\Rule::gt([ 'a' ]) ]); // $validation->addRules('lt', [ \Gzhegow\Validator\Rule\Kit\Rule::lt([ 'c' ]) ]); // $validation->addRules('lte', [ \Gzhegow\Validator\Rule\Kit\Rule::lte([ 'b' ]) ]); // $validation->addRules('gte', [ \Gzhegow\Validator\Rule\Kit\Rule::gte([ 'b' ]) ]); // // // $validation->addRules('eq_field', [ \Gzhegow\Validator\Rule\Kit\Rule::eq_field([ '_field_b' ]) ]); // $validation->addRules('neq_field', [ \Gzhegow\Validator\Rule\Kit\Rule::neq_field([ '_field_a' ]) ]); // $validation->addRules('gt_field', [ \Gzhegow\Validator\Rule\Kit\Rule::gt_field([ '_field_a' ]) ]); // $validation->addRules('lt_field', [ \Gzhegow\Validator\Rule\Kit\Rule::lt_field([ '_field_c' ]) ]); // $validation->addRules('lte_field', [ \Gzhegow\Validator\Rule\Kit\Rule::lte_field([ '_field_b' ]) ]); // $validation->addRules('gte_field', [ \Gzhegow\Validator\Rule\Kit\Rule::gte_field([ '_field_b' ]) ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'json' => json_encode([ 1, 2, 3 ]), // ]); // // $validation->addRules('json', [ \Gzhegow\Validator\Rule\Kit\Rule::json() ]); // })($validation); // // (function ($validation) { // $validation->addData([ // '_field_in' => [ 1, 2, 3 ], // 'in_field' => 1, // 'in_not_field' => 4, // // // 'in_enum' => 1, // 'in_not_enum' => 4, // 'in_not' => 4, // 'in' => 1, // ]); // // $validation->addRules('in_field', [ \Gzhegow\Validator\Rule\Kit\Rule::in_field([ '../_field_in' ]) ]); // $validation->addRules('in_not_field', [ \Gzhegow\Validator\Rule\Kit\Rule::in_not_field([ '../_field_in' ]) ]); // // // $validation->addRules('in_enum', [ \Gzhegow\Validator\Rule\Kit\Rule::in_enum([ '\Gzhegow\Validator\Tests\Enum\HelloWorldBackedEnum' ]) ]); // $validation->addRules('in_not_enum', [ \Gzhegow\Validator\Rule\Kit\Rule::in_not_enum([ '\Gzhegow\Validator\Tests\Enum\HelloWorldBackedEnum' ]) ]); // $validation->addRules('in_not', [ \Gzhegow\Validator\Rule\Kit\Rule::in_not([ [ 1, 2, 3 ] ]) ]); // $validation->addRules('in', [ \Gzhegow\Validator\Rule\Kit\Rule::in([ [ 1, 2, 3 ] ]) ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'ip_in_subnets' => '127.0.0.1', // 'ip_in_subnets_v4' => '127.0.0.1', // 'ip_in_subnets_v6' => '::1', // ]); // // $validation->addRules('ip_in_subnets', [ \Gzhegow\Validator\Rule\Kit\Rule::ip_in_subnets([ '127.0.0.1/32' ]) ]); // $validation->addRules('ip_in_subnets_v4', [ \Gzhegow\Validator\Rule\Kit\Rule::ip_in_subnets_v4([ '127.0.0.1/32' ]) ]); // $validation->addRules('ip_in_subnets_v6', [ \Gzhegow\Validator\Rule\Kit\Rule::ip_in_subnets_v6([ '::1/128' ]) ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'is_of_a' => new \DateTime('@5'), // 'is_of_class' => new \DateTime('@5'), // 'is_of_subclass' => new \DateTime('@5'), // 'struct_is_a' => \DateTime::class, // 'struct_is_class' => \DateTime::class, // 'struct_is_subclass' => \DateTime::class, // ]); // // $validation->addRules('is_of_a', [ \Gzhegow\Validator\Rule\Kit\Rule::is_of_a([ \DateTimeInterface::class ]) ]); // $validation->addRules('is_of_class', [ \Gzhegow\Validator\Rule\Kit\Rule::is_of_class([ \DateTime::class ]) ]); // $validation->addRules('is_of_subclass', [ \Gzhegow\Validator\Rule\Kit\Rule::is_of_subclass([ \DateTimeInterface::class ]) ]); // $validation->addRules('struct_is_a', [ \Gzhegow\Validator\Rule\Kit\Rule::struct_is_a([ \DateTimeInterface::class ]) ]); // $validation->addRules('struct_is_class', [ \Gzhegow\Validator\Rule\Kit\Rule::struct_is_class([ \DateTime::class ]) ]); // $validation->addRules('struct_is_subclass', [ \Gzhegow\Validator\Rule\Kit\Rule::struct_is_subclass([ \DateTimeInterface::class ]) ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'contains' => 'hello123', // 'ctype_alnum' => 'hello123', // 'ctype_alpha' => 'hello', // 'ctype_digit' => '123', // 'ends' => 'hello123', // 'regex_not' => '123', // 'regex' => 'hello123', // 'starts' => 'hello123', // ]); // // $validation->addRules('contains', [ \Gzhegow\Validator\Rule\Kit\Rule::contains([ 'ello1' ]) ]); // $validation->addRules('ctype_alnum', [ \Gzhegow\Validator\Rule\Kit\Rule::ctype_alnum() ]); // $validation->addRules('ctype_alpha', [ \Gzhegow\Validator\Rule\Kit\Rule::ctype_alpha() ]); // $validation->addRules('ctype_digit', [ \Gzhegow\Validator\Rule\Kit\Rule::ctype_digit() ]); // $validation->addRules('ends', [ \Gzhegow\Validator\Rule\Kit\Rule::ends([ '123' ]) ]); // $validation->addRules('regex_not', [ \Gzhegow\Validator\Rule\Kit\Rule::regex_not([ '[a-z]' ]) ]); // $validation->addRules('regex', [ \Gzhegow\Validator\Rule\Kit\Rule::regex([ '[a-z0-9]' ]) ]); // $validation->addRules('starts', [ \Gzhegow\Validator\Rule\Kit\Rule::starts([ 'hello' ]) ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'array' => [ 0 => 1, 2 => 2, 'key3' => 3 ], // 'dict' => [ 'key1' => 1, 'key2' => 2, 'key3' => 3 ], // 'gettype' => 1.0, // 'list' => [ 1, 2, 3 ], // 'object' => new \stdClass(), // 'uuid' => 'c511ee5f-2351-4b92-a544-769ce1eddfea', // ]); // // $validation->addRules('array', [ \Gzhegow\Validator\Rule\Kit\Rule::array() ]); // $validation->addRules('dict', [ \Gzhegow\Validator\Rule\Kit\Rule::dict() ]); // $validation->addRules('gettype', [ \Gzhegow\Validator\Rule\Kit\Rule::gettype([ 'double' ]) ]); // $validation->addRules('list', [ \Gzhegow\Validator\Rule\Kit\Rule::list() ]); // $validation->addRules('object', [ \Gzhegow\Validator\Rule\Kit\Rule::object() ]); // $validation->addRules('uuid', [ \Gzhegow\Validator\Rule\Kit\Rule::uuid() ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'date' => '1970-01-01', // 'date_tz_named' => '1970-01-01 EET', // 'date_tz_offset' => '1970-01-01 +0100', // 'date_tz' => '1970-01-01 EET', // 'interval' => 'P1D', // 'timezone_named' => 'EET', // 'timezone_offset' => '+0100', // 'timezone' => 'EET', // ]); // // $validation->addRules('date', [ \Gzhegow\Validator\Rule\Kit\Rule::date([ 'Y-m-d' ]) ]); // $validation->addRules('date_tz_named', [ \Gzhegow\Validator\Rule\Kit\Rule::date_tz_named([ 'Y-m-d T' ]) ]); // $validation->addRules('date_tz_offset', [ \Gzhegow\Validator\Rule\Kit\Rule::date_tz_offset([ 'Y-m-d O' ]) ]); // $validation->addRules('date_tz', [ \Gzhegow\Validator\Rule\Kit\Rule::date_tz([ 'Y-m-d T' ]) ]); // $validation->addRules('interval', [ \Gzhegow\Validator\Rule\Kit\Rule::interval() ]); // $validation->addRules('timezone_named', [ \Gzhegow\Validator\Rule\Kit\Rule::timezone_named() ]); // $validation->addRules('timezone_offset', [ \Gzhegow\Validator\Rule\Kit\Rule::timezone_offset() ]); // $validation->addRules('timezone', [ \Gzhegow\Validator\Rule\Kit\Rule::timezone() ]); // })($validation); // // (function ($validation) use ($ffn) { // $validation->addData([ // 'file' => $ffn->root() . '/tests/var/file.txt', // 'image' => $ffn->root() . '/tests/var/file.jpg', // ]); // // $validation->addRules('file', [ \Gzhegow\Validator\Rule\Kit\Rule::file([ [ 'txt' ], [ 'text/' ] ]) ]); // $validation->addRules('image', [ \Gzhegow\Validator\Rule\Kit\Rule::image([ [ 'jpg' ], [ 'image/' ] ]) ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'address_ip' => '127.0.0.1', // 'address_ip_v4' => '127.0.0.1', // 'address_ip_v6' => '::1', // 'address_mac' => '00-B0-D0-63-C2-26', // 'subnet' => '127.0.0.1/32', // 'subnet_v4' => '127.0.0.1/32', // 'subnet_v6' => '::1/128', // ]); // // $validation->addRules('address_ip', [ \Gzhegow\Validator\Rule\Kit\Rule::address_ip() ]); // $validation->addRules('address_ip_v4', [ \Gzhegow\Validator\Rule\Kit\Rule::address_ip_v4() ]); // $validation->addRules('address_ip_v6', [ \Gzhegow\Validator\Rule\Kit\Rule::address_ip_v6() ]); // $validation->addRules('address_mac', [ \Gzhegow\Validator\Rule\Kit\Rule::address_mac() ]); // $validation->addRules('subnet', [ \Gzhegow\Validator\Rule\Kit\Rule::subnet() ]); // $validation->addRules('subnet_v4', [ \Gzhegow\Validator\Rule\Kit\Rule::subnet_v4() ]); // $validation->addRules('subnet_v6', [ \Gzhegow\Validator\Rule\Kit\Rule::subnet_v6() ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'email' => 'name@gmail.com', // // 'phone_real' => '+375 (29) 123-45-67', // 'phone' => '+375 (29) 123-45-67', // // 'tel_real' => '+375291234567', // 'tel' => '+375291234567', // ]); // // $validation->addRules('email', [ \Gzhegow\Validator\Rule\Kit\Rule::email() ]); // // $validation->addRules('phone_real', [ \Gzhegow\Validator\Rule\Kit\Rule::phone_real() ]); // $validation->addRules('phone', [ \Gzhegow\Validator\Rule\Kit\Rule::phone() ]); // // $validation->addRules('tel_real', [ \Gzhegow\Validator\Rule\Kit\Rule::tel_real() ]); // $validation->addRules('tel', [ \Gzhegow\Validator\Rule\Kit\Rule::tel() ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'host' => 'https://google.com', // 'link' => 'my/url/link', // 'url' => 'https://google.com/my/url/link', // ]); // // $validation->addRules('host', [ \Gzhegow\Validator\Rule\Kit\Rule::host() ]); // $validation->addRules('link', [ \Gzhegow\Validator\Rule\Kit\Rule::link() ]); // $validation->addRules('url', [ \Gzhegow\Validator\Rule\Kit\Rule::url() ]); // })($validation); // // (function ($validation) { // $validation->addData([ // 'bool' => true, // 'boolean' => true, // 'decimal' => '1.10', // 'double' => 1.01, // 'float' => 1.01, // 'int' => 1, // 'integer' => 1, // 'num' => 1.0, // 'numeric' => '1', // 'numeric_float' => '1.01', // 'numeric_int' => '1.0', // 'string' => 'hello', // 'trim' => ' hello ', // // // // > yes/y, no/n, true, false, 1, 0 // 'userbool' => 'yes', // 'userbool_false' => '0', // 'userbool_true' => '1', // ]); // // $validation->addRules('bool', [ \Gzhegow\Validator\Rule\Kit\Rule::bool() ]); // $validation->addRules('boolean', [ \Gzhegow\Validator\Rule\Kit\Rule::boolean() ]); // $validation->addRules('decimal', [ \Gzhegow\Validator\Rule\Kit\Rule::decimal([ 2 ]) ]); // $validation->addRules('double', [ \Gzhegow\Validator\Rule\Kit\Rule::double() ]); // $validation->addRules('float', [ \Gzhegow\Validator\Rule\Kit\Rule::float() ]); // $validation->addRules('int', [ \Gzhegow\Validator\Rule\Kit\Rule::int() ]); // $validation->addRules('integer', [ \Gzhegow\Validator\Rule\Kit\Rule::integer() ]); // $validation->addRules('num', [ \Gzhegow\Validator\Rule\Kit\Rule::num() ]); // $validation->addRules('numeric', [ \Gzhegow\Validator\Rule\Kit\Rule::numeric() ]); // $validation->addRules('numeric_float', [ \Gzhegow\Validator\Rule\Kit\Rule::numeric_float() ]); // $validation->addRules('numeric_int', [ \Gzhegow\Validator\Rule\Kit\Rule::numeric_int() ]); // $validation->addRules('string', [ \Gzhegow\Validator\Rule\Kit\Rule::string() ]); // $validation->addRules('trim', [ \Gzhegow\Validator\Rule\Kit\Rule::trim() ]); // // // $validation->addRules('userbool', [ \Gzhegow\Validator\Rule\Kit\Rule::userbool() ]); // $validation->addRules('userbool_false', [ \Gzhegow\Validator\Rule\Kit\Rule::userbool_false() ]); // $validation->addRules('userbool_true', [ \Gzhegow\Validator\Rule\Kit\Rule::userbool_true() ]); // })($validation); // // $status = $validation->passes(); // $ffn->print($status, $validation->messages()); // $ffn->print_array_multiline($validation->getRules()); // die(); // > TEST // > создаем валидатор и запускаем проверку $fn = function () use ($ffn) { $ffn->print('TEST 1'); echo PHP_EOL; $uuid = 'e08e6870-1e13-47c0-bf86-cb0944f6f4bf'; $validation = \Gzhegow\Validator\Validator::new(); $data = [ // uuid_missing 'uuid_null' => null, 'uuid_empty_string' => '', 'uuid_wrong' => 'test', 'uuid' => $uuid, ]; $validation = $validation ->addData($data) ->addRulesMap([ 'uuid_missing' => 'present|uuid', 'uuid_null' => 'present|uuid', 'uuid_empty_string' => 'present|uuid', 'uuid_wrong' => 'present|uuid', 'uuid' => 'present|uuid', ]) ; $messages = $validation->messages(); $ffn->print_array_multiline($messages, 2); }; $ffn->assert_stdout($fn, [], ' "TEST 1" ### [ "uuid_missing" => [ "validation.present" ], "uuid_null" => [ "validation.uuid" ], "uuid_empty_string" => [ "validation.uuid" ], "uuid_wrong" => [ "validation.uuid" ] ] ### '); // > TEST // > проверяем вложенный массив $fn = function () use ($ffn) { $ffn->print('TEST 2'); echo PHP_EOL; $validation = \Gzhegow\Validator\Validator::new(); $data = [ // uuid_missing 'uuid_null' => null, 'uuid_empty_string' => '', 'uuid_wrong' => 'test', 'uuid' => \Gzhegow\Lib\Lib::random()->uuid(), // 'my_nested_array' => [ // uuid_missing 'uuid_null' => null, 'uuid_empty_string' => '', 'uuid_wrong' => 'test', 'uuid' => \Gzhegow\Lib\Lib::random()->uuid(), // 'my_nested_array' => [ // uuid_missing 'uuid_null' => null, 'uuid_empty_string' => '', 'uuid_wrong' => 'test', 'uuid' => \Gzhegow\Lib\Lib::random()->uuid(), ], ], ]; $validation = $validation ->addData($data) ->addRulesMap([ // > можно перечислять ключи вручную 'uuid_missing' => 'present|uuid', 'uuid_null' => 'present|uuid', 'uuid_empty_string' => 'present|uuid', 'uuid_wrong' => 'present|uuid', 'uuid' => 'present|uuid', ]) ->addRulesMap([ // > ещё можно перечислять вложенные ключи вручную 'my_nested_array' => 'array', 'my_nested_array.uuid_missing' => 'present|uuid', 'my_nested_array.uuid_null' => 'present|uuid', 'my_nested_array.uuid_empty_string' => 'present|uuid', 'my_nested_array.uuid_wrong' => 'present|uuid', 'my_nested_array.uuid' => 'present|uuid', ]) ->addRulesMap([ // > или можно использовать символ `*`, чтобы указать "все" // > но, надо понимать, что все означает "все имеющиеся", то есть если ключ нужен, а его нет, то проверки не будет 'my_nested_array.my_nested_array' => 'array', 'my_nested_array.my_nested_array.*' => 'present|uuid', ]) ; $rules = $validation->rules(); $ffn->print_array_multiline($rules, 2); $messages = $validation->messages(); $ffn->print_array_multiline($messages, 2); }; $ffn->assert_stdout($fn, [], ' "TEST 2" ### [ "uuid_missing" => "present|uuid", "uuid_null" => "present|uuid", "uuid_empty_string" => "present|uuid", "uuid_wrong" => "present|uuid", "uuid" => "present|uuid", "my_nested_array" => "array", "my_nested_array.uuid_missing" => "present|uuid", "my_nested_array.uuid_null" => "present|uuid", "my_nested_array.uuid_empty_string" => "present|uuid", "my_nested_array.uuid_wrong" => "present|uuid", "my_nested_array.uuid" => "present|uuid", "my_nested_array.my_nested_array" => "array", "my_nested_array.my_nested_array.*" => "present|uuid" ] ### ### [ "uuid_missing" => [ "validation.present" ], "uuid_null" => [ "validation.uuid" ], "uuid_empty_string" => [ "validation.uuid" ], "uuid_wrong" => [ "validation.uuid" ], "my_nested_array.uuid_missing" => [ "validation.present" ], "my_nested_array.uuid_null" => [ "validation.uuid" ], "my_nested_array.uuid_empty_string" => [ "validation.uuid" ], "my_nested_array.uuid_wrong" => [ "validation.uuid" ], "my_nested_array.my_nested_array.uuid_null" => [ "validation.uuid" ], "my_nested_array.my_nested_array.uuid_empty_string" => [ "validation.uuid" ], "my_nested_array.my_nested_array.uuid_wrong" => [ "validation.uuid" ] ] ### '); // > TEST // > проверка механизмов фильтрации и умолчаний // > например, (string) '1' часто приводится к (int) 1, перед тем как его проверить // > можно указать "значение по-умолчанию" // > перед проверкой если (value === default) - поле считается валидным $fn = function () use ($ffn) { $ffn->print('TEST 3'); echo PHP_EOL; $validation = \Gzhegow\Validator\Validator::new(); $data = [ 0 => '0', 1 => '1', 2 => '2', // 'key0' => '0', 'key1' => '1', 'key2' => '2', // 'key3' => [ 0 => '0', 1 => '1', 2 => '2', // 'key0' => '0', 'key1' => '1', 'key2' => '2', // 'key3' => [ 0 => '0', 1 => '1', 2 => '2', // 'key0' => '0', 'key1' => '1', 'key2' => '2', ], ], ]; $validation = $validation ->addData($data) // // > обратите внимание, что правила предполагают, что значение больше нуля, но "по-умолчанию" - 0 // > если в поле окажется 0 или значение, которое с помощью фильтра станет 0, правила не применяются и значение валидно ->addRules('0', 'present|int|gt:0') ->addFilters('0', 'intval') ->addDefault('0', [ 0 ]) ->addRules('1', 'present|string|gt:1', $filter = 'strval', $default = [ '1' ]) ->addRules('2', 'present|string|gt:2') // ->addRules('key0', 'present|int|gt:0') ->addFilters('key0', 'intval') ->addDefault('key0', [ 0 ]) ->addRules('key1', 'present|string|gt:1', $filter = 'strval', $default = [ '1' ]) ->addRules('key2', 'present|string|gt:2') // // > фильтры тоже работают при указании со звездочкой ->addRules('key3.*', 'present|int|gt:1', 'intval') // // > одна звездочка означает один уровень, указывать "все уровни" избыточно и валидатором не предусматривается ->addRules('key3.*.*', 'present|int|gt:1') ; // $data = $validation->data(); // > получить все исходные данные // $dataValidated = $validation->dataValidated(); // > получить исходные данные, к которым применились правила // $all = $validation->all(); // > получить все итоговые данные (валидные и не валидные) $valid = $validation->valid(); // > получить итоговые данные у которых нет сообщений об ошибках (в т.ч. дефолты) $invalid = $validation->invalid(); // > получить итоговые данные у которых есть сообщения об ошибках (на дефолты не применяются) // $validated = $validation->validated(); // > получить итоговые данные к которым применились правила (кроме дефолтов) // $errors = $validation->errors(); // > получить все ошибки в виде двумерного массива $messages = $validation->messages(); // > получить все ошибки в виде массива строк $ffn->print_array_multiline($valid, 3); echo PHP_EOL; $ffn->print_array_multiline($invalid, 3); echo PHP_EOL; $ffn->print_array_multiline($messages, 2); }; $ffn->assert_stdout($fn, [], ' "TEST 3" ### [ 0 => 0, 1 => "1", "key0" => 0, "key1" => "1", "key3" => [ 2 => 2, "key2" => 2, "key3" => [ 2 => "2", "key2" => "2" ] ] ] ### ### [ 2 => "2", "key2" => "2", "key3" => [ 0 => 0, 1 => 1, "key0" => 0, "key1" => 1, "key3" => [ 0 => "0", 1 => "1", "key0" => "0", "key1" => "1" ] ] ] ### ### [ 2 => [ "validation.gt" ], "key2" => [ "validation.gt" ], "key3.0" => [ "validation.gt" ], "key3.1" => [ "validation.gt" ], "key3.key0" => [ "validation.gt" ], "key3.key1" => [ "validation.gt" ], "key3.key3.0" => [ "validation.gt" ], "key3.key3.1" => [ "validation.gt" ], "key3.key3.key0" => [ "validation.gt" ], "key3.key3.key1" => [ "validation.gt" ] ] ### '); // > TEST // > проверка режимов API и WEB // > в режиме API из запроса выбрасываются NULL, а в режиме WEB - пустые строки $fn = function () use ($ffn) { $ffn->print('TEST 4'); echo PHP_EOL; $builder = \Gzhegow\Validator\Validator::new(); $data = [ 'user_sent_null' => null, 'user_sent_empty_string' => '', ]; $validation = $builder ->addData($data) ->addRulesMap([ 'user_sent_null' => 'present|string', 'user_sent_empty_string' => 'present|string', ]) ; $validation ->modeWeb(false) ->modeApi(false) ; $messages = $validation->messages(); $ffn->print_array_multiline($messages, 2); echo PHP_EOL; $validation ->modeWeb(true) ->modeApi(false) ; $messages = $validation->messages(); $ffn->print_array_multiline($messages, 2); echo PHP_EOL; $validation ->modeWeb(false) ->modeApi(true) ; $messages = $validation->messages(); $ffn->print_array_multiline($messages, 2); echo PHP_EOL; $validation ->modeWeb(true) ->modeApi(true) ; $messages = $validation->messages(); $ffn->print_array_multiline($messages, 2); echo PHP_EOL; }; $ffn->assert_stdout($fn, [], ' "TEST 4" ### [ "user_sent_null" => [ "validation.string" ] ] ### ### [ "user_sent_null" => [ "validation.string" ], "user_sent_empty_string" => [ "validation.present" ] ] ### ### [ "user_sent_null" => [ "validation.present" ] ] ### ### [ "user_sent_null" => [ "validation.present" ], "user_sent_empty_string" => [ "validation.present" ] ] ### '); // > TEST // > проверка разных способов указания нескольких правил и режимов маппинга на массив и объект1 $fn = function () use ($ffn) { $ffn->print('TEST 5'); echo PHP_EOL; $validation = \Gzhegow\Validator\Validator::new(); $validation->addData([ 'users' => [ '21' => [ 'id' => null, 'code' => null, 'name' => null, ], '22' => [ 'id' => null, 'code' => null, 'name' => null, ], ], ]); $validation->addRules('users.*.id', 'present|string|size_min:1'); $validation->addFilters('users.*.id', 'intval'); $validation->addDefault('users.*.id', [ '0' ]); $validation->addRules( $keyWildcard = 'users.*.name', $rules = 'present|string|size_min:1', $filter = 'strval', $default = [ 'User' ] ); $validation->addRulesMap( $rules = [ 'users.21.code' => [ 'present', 'string|size_min:1' ], 'users.22.code' => [ \Gzhegow\Validator\Rule\Kit\Rule::present(), \Gzhegow\Validator\Rule\Kit\Rule::string(), \Gzhegow\Validator\Rule\Kit\Rule::size_min([ 1 ]), ], ] ); $status = $validation->passes(); $messages = $validation->messages(); $ffn->print($status); $ffn->print_array_multiline($messages, 2); echo PHP_EOL; $validAttributes = $validation->validAttributes(); $invalidAttributes = $validation->invalidAttributes(); $ffn->print_array_multiline($validAttributes, 2); $ffn->print_array_multiline($invalidAttributes, 2); echo PHP_EOL; $bindArray = []; $validation->valid($bindArray); $bindObject = new \stdClass(); $validation->valid($bindObject); $ffn->print_array_multiline($bindArray, 3); $ffn->print_array_multiline((array) $bindObject, 2); }; $ffn->assert_stdout($fn, [], ' "TEST 5" FALSE ### [ "users.21.code" => [ "validation.string" ], "users.22.code" => [ "validation.string" ] ] ### ### [ "users.21.id" => "0", "users.21.name" => "User", "users.22.id" => "0", "users.22.name" => "User" ] ### ### [ "users.21.code" => NULL, "users.22.code" => NULL ] ### ### [ "users" => [ 21 => [ "id" => "0", "name" => "User" ], 22 => [ "id" => "0", "name" => "User" ] ] ] ### ### [ "users" => (object) [ 21 => (object) [ "id" => "0", "name" => "User" ], 22 => (object) [ "id" => "0", "name" => "User" ] ] ] ### ');