ava239 / validator
data validator
Installs: 2 867
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Requires
- php: >=8.1
Requires (Dev)
- phpstan/extension-installer: ^1.3.1
- phpstan/phpstan: ^1.10.38
- phpstan/phpstan-phpunit: ^1.3.15
- phpunit/phpunit: ^10.4.1
- squizlabs/php_codesniffer: ^3.5.5
- symfony/var-dumper: ^6.3.5
README
Validator library
Inspired by yup (JavaScript library)
Can validate strings, numbers, arrays by shape.
Also supports custom validators.
Basic usage example:
<?php use Ava239\Validator\Validator; $v = new \Ava239\Validator\Validator(); // strings $schema = $v->required()->string(); $schema->isValid('what does the fox say'); // true $schema->isValid(''); // false // numbers $schema = $v->required()->number()->positive(); $schema->isValid(-10); // false $schema->isValid(10); // true // array with shape check $schema = $v->array()->sizeof(2)->shape([ 'name' => $v->string()->required(), 'age' => $v->number()->positive(), ]); $schema->isValid(['name' => 'kolya', 'age' => 100]); // true $schema->isValid(['name' => '', 'age' => null]); // false // custom validator $fn = fn($value, $start) => str_starts_with($value, $start); $v->addValidator('string', 'startWith', $fn); $schema = $v->string()->test('startWith', 'H'); $schema->isValid('exlet'); // false $schema->isValid('Hack'); // true
More examples in tests
Factory object
$v = new \Ava239\Validator\Validator();
This will return factory object. It`s basic for your later usage and only one instance is really needed (but you can create as many as you wish).
It can produce concrete validator instances which implement ValidatorBase
interface and supposed to validate single variable of defined type.
Types implemented at this moment:
- string (created by
string()
method) - number (created by
number()
method) - array (created by
array()
method)
This object also responsible for adding custom validators to concrete validation objects created by it.
Use addValidator($type, $name, $validatorFunction)
to add it, where:
$type
is one ofstring
,number
,array
. defines data type where validator will be available$name
is validator name. you will call it by that name$validatorFunction
is closure with at least one parameter which returns boolean. First parameter passed to function will be thing we are validating
Running custom validations
Custom validations called after adding custom validator to factory object.
Full example:
$fn = fn($value, $start) => str_starts_with($value, $start); $v->addValidator('string', 'startWith', $fn); $schema = $v->string()->test('startWith', 'H');
You call test()
function on concrete validator with such params:
- validator name
- any number of additional params (optional)
List of included validators by data type
String
contains($substring)
- tests if string contains $substringminLength($length)
- tests if string length is at least $lengthmaxLength($length)
- tests if string length does not exceed $lengthrequired()
- tests if string is not empty
Number
positive()
- tests if number is positive (> 0)range($min, $max)
- tests if number is between $min and $maxrequired()
- tests if value is a number (without this null is also valid value)
Array
sizeof($length)
- tests if array contains at least $length elementsrequired()
- tests if value is an array (without this null is also valid value)shape($shape)
- tests if array is described by a $shape, where $shape is associative array where values are validator objects created by afactory object
.
This method returns true only if every sub-validator is valid.
Allows any reasonable level of nesting (you can put array with shape validation as a key for shape validation).
Error messages
As of version 1.1.0 you can add error messages for each validation.
To get error list there was validate($data)
method added which will act as isValid($data)
with a difference it will return validator object, so you can chain getErrors()
method.
Let's get to example:
$schema->shape( [ 'name' => $v->string()->required("error name"), 'age' => $v->number()->positive("error age"), 'surname' => $v->string()->required("error surname"), 'passport' => $v->array()->required()->shape( [ 'number' => $v->number()->required("error number"), 'series' => $v->number()->required("error series"), 'sub' => $v->array()->required()->shape( [ 'num' => $v->number()->required("error subnum"), ], 'error sub' ), ], 'error passport' ), ], 'error array' );
Here we define shape with error messages for most of the validations.
You can define error message as last parameter of any validation function.
So if it is validation with params you call it like that: contains('substring', 'error message')
You also can define parameter name to use it in error messages. To do so just add as parameter on validator creation call (string()
, number()
or array()
).
It can be accessed as {{name}}
in any validation message:
$fn = fn ($value, $start) => str_starts_with($value, $start); $v->addValidator('string', 'startWith', $fn, 'test msg {{name}}'); $v->string('test name')->test('startWith', 'H');
If error occurs message will be parsed to "test msg test name"
Error array structure
It is flat associative array (no matter how much nesting you used) key => message
.
Keys have such structure:
- validation name for any basic validation
_
for shape validation- nested keys represented by dot notation.
Keys for example above:
'_' // shape error 'age.positive' // age field, positive validation error 'name.required' // name field, required validation error 'passport._' // passport field, shape error 'passport.series.required' // passport field, series sub-field, required validation error 'passport.number.valid' // passport field, number sub-field, number validation error // if value doesn't match expected data type it generates error with key "valid" // it's applied for array, number, string validations // if this error occurs no further validations will be performed for this field 'passport.sub._' // passport field, "sub" sub-field, shape error 'passport.sub.num.required' // passport field, "sub" sub-field, "num" sub-sub-field required validation error
Notice above how data type errors handled.
It is expected what you convert error messages structure as you wish after you get them.