krak / validation
Functional validation library
Installs: 1 639
Dependents: 2
Suggesters: 1
Security: 0
Stars: 3
Watchers: 3
Forks: 2
Open Issues: 6
Requires
- krak/cargo: ^0.2.3
- krak/invoke: ^0.1.0
- nikic/iter: ^1.4
- peridot-php/leo: ^1.6
Requires (Dev)
- doctrine/common: ^2.5
- peridot-php/peridot: ^1.19
- phake/phake: ^2.0
- symfony/validator: ^2.7
- symfony/var-dumper: ^2.0
Suggests
- ext-ctype: needed for string validators
- doctrine/orm: needed for any of the doctrine validators
- symfony/validator: needed for the symfony validators
README
The Krak Validation library is a functional and simple approach and interface to validation. It was made out of the need a validation library with a simple interface and configuration. Other leading validators like Respect, Zend, or Symfony have a lot of complexity in their API and adding an actual validator will require adding several classes in some instances.
Krak Validation changes all of this by taking a functional approach to validation where every validator is just a function or instance of Krak\Validation\Validator
. This design lends itself easily for extending, custom validators, and decorators. It comes bundled with a Krak\Validation\Kernel
which manages validators to provide a simple, fluent, and customizable interface for utilizing validators.
- Installation
- Usage
- Validators
- Validation Packages
- Core Validation Package
- Doctrine Validation Package
- API
Installation
Install with composer at krak/validation
Usage
<?php $validation = new Krak\Validation\Kernel(); $validator = $validation->make([ 'name' => 'required|string', 'age' => 'optional|integer|between:18,25', ]); $violations = $validator->validate([ 'name' => 'RJ', 'age' => 17, ]); if ($violations) { // you can also check $validator->failed() print_r($violations->format()); // format into an array of error messages }
This will print something like this:
Array
(
[age] => Array
(
[0] => The Age field must be between 18 and 25
)
)
Validators
A validator can be a Krak\Validation\Validator
, or any callable that accepts a value and returns null on success and a violation on failure.
Validators implement the following signature:
function($value, array $ctx = [])
The second parameter can typically be left out, but is used to pass additional information into the validator. A good example is a PSR Container so that dependencies can be lazy loaded at time of actual validation.
Violations
Creating violations is easy with the violate
or violations
function. For most validators, you'll simply be creating one violation.
<?php use Krak\Validation; /** enforces that a value equals a specific value */ function equalsStringValidator($match) { return function($value, array $ctx = []) use ($match) { if ($value == $match) { return; } return Validation\violate('equals_string', [ 'match' => $match ]); }; } $v = equalsStringValidator('foo'); $v('foo'); // returns null $violation = $v('bar'); // return a Krak\Validation\Violation
In some cases, one validator can return multiple violations. In that case, we just use the violations
to create a violation collection. You can checkout the Krak\Validation\Validators\collection
validator to see how to create a violation collection.
Throwing Violations
Once you have a violation or a violation collection, you can optionally throw them as exceptions to be handled upstream.
<?php try { $violation->abort(); } catch (Krak\Validation\Exception\ViolationException $e) { assert($e->violation === $violation); }
Asserting Data
A very common practice is using the Validation Kernel to make and validate domain data and then throw a ViolationException if any violations occur. This can be done simply via the assert
method.
$validation = new Krak\Validation\Kernel(); $validation->make([ 'name' => 'required|string', 'age' => 'optional|integer|between:18,25', ])->assert(['name' => 'RJ', 'age' => 100]); // this will have thrown a ViolationException due to the age constraint
You can then easily catch the ViolationException
upstream and format the violation into readable errors:
try { return response($storeUser($userData), 201); } catch (Krak\Validation\Exception\ViolationException $e) { return response([ 'errors' => $e->violation->format(), ], 422); }
Validation Packages
Validation Packages are simple extensions to the Validation\Kernel that register validators and messages into the system.
Creating a Validation Package
To create a validation package, you need to extend the ValidationPackage
interface.
interface ValidationPackage { public function withValidation(Kernel $validation); }
From there, you can configure the validation kernel any which way you need.
Typically, you'll just use the validators
, messages
, and aliases
methods to add keyed validations and corresponding methods or aliases.
An example Validation Package would look like:
<?php use Krak\Validation; class AcmeValidationPackage implements Validation\ValidationPackage { public function withValidation(Validation\Kernel $v) { $v->validators([ 'integer' => 'intValidator', // name of intValidator func 'min' => MinValidator::class // name of MinValidator class ]); $v->messages([ 'integer' => 'The {{attribute}} is not a valid integer', 'min' => 'The {{attribute}} size must be greater than or equal to {{min}}', ]); $v->aliases([ 'int' => 'integer', ]); } }
The validators would be defined in different files like so:
use Krak\Validation; // intValidator.php function intValidator() { return function($v) { return !is_int($v) ? Validation\violate('integer') : null; }; } // MinValidator.php class MinValidator implements Validation\Validator { private $min; public function __construct($min) { $this->min = $min; } public function validate($value, array $context = []) { return $value < $min ? Validation\violate('min', ['min' => $this->min]) : null; } }
Core Validation Package
The Core Validation package defines a bunch of the normal useful validators.
all
Validates an array with the given validator. If any element in the array fails the validation, a violation will be returned.
Definition: Krak\Validation\Validators\forAll($validator)
Simple Usage:
$validator->make('all:integer')->validate([1,2,3]);
Advanced Usage:
use function Krak\Validation\Validators\{forAll}; $validator->make(forAll('integer|between:1,3'))->validate([1,2,3])
Standalone Usage:
use function Krak\Validation\Validators\{forAll, typeInteger}; forAll(typeInteger())([2,3]);
alpha
Wraps the ctype_alpha
function and validates a string to verify only alpha characteres.
Definition: Krak\Validation\Validators\alpha()
Simple Usage:
$validator->make('alpha')->validate('abc');
Standalone Usage:
use function Krak\Validation\Validators\{alpha}; alpha()('123');
alpha_num
Wraps the ctype_alnum
function and validates a string to make sure it's alpha numeric.
Definition: Krak\Validation\Validators\alphaNum()
Simple Usage:
$validator->make('alpah_num')->validate('abc123');
Standalone Usage:
use function Krak\Validation\Validators\{alphaNum}; alphaNum()('abc123');
array
Verifies that the value is an array using is_array
.
Definition: Krak\Validation\Validators\typeArray()
Simple Usage:
$validator->make('array')->validate();
Standalone Usage:
use function Krak\Validation\Validators\{typeArray}; typeArray()([]);
between
Validates a value's size is between two values inclusively.
Definition: Krak\Validation\Validators\between($min, $max)
Simple Usage:
$validator->make('between:1,2')->validate(2);
Standalone Usage:
use function Krak\Validation\Validators\{between}; between(1, 2)(2);
boolean
Validates a value is a boolean. true
, false
, "0"
, "1"
, 0
, 1
are all instances of boolean.
Definition: Krak\Validation\Validators\typeBoolean()
Simple Usage:
$validator->make('boolean')->validate(true);
Standalone Usage:
use function Krak\Validation\Validators\{typeBoolean}; typeBoolean()(true);
date
Validates a string is a valid date using strototime
. Anything that strtotime
accepts is accepted here.
Definition: Krak\Validation\Validators\date()
Simple Usage:
$validator->make('date')->validate('2017-08-11');
Standalone Usage:
use function Krak\Validation\Validators\{date}; date()('2017-08-11');
digits
Validates a string is of type digits using the ctype_digits
function.
Definition: Krak\Validation\Validators\digits()
Simple Usage:
$validator->make('digits')->validate('123');
Standalone Usage:
use function Krak\Validation\Validators\{digits}; digits()('123');
double
Validates a value is a double using is_double
.
Definition: Krak\Validation\Validators\double()
Simple Usage:
$validator->make('double')->validate(4.2);
Standalone Usage:
use function Krak\Validation\Validators\{double}; double()(4.2);
Validates that a string matches an email regex.
Definition: Krak\Validation\Validators\regexEmail()
Simple Usage:
$validator->make('email')->validate('username@gmail.com');
Standalone Usage:
use function Krak\Validation\Validators\{regexEmail}; regexEmail()('username@gmail.com');
exists
Alias of required
.
float
Validates a value is a float using is_float
.
Definition: Krak\Validation\Validators\float()
Simple Usage:
$validator->make('float')->validate(4.2);
Standalone Usage:
use function Krak\Validation\Validators\{float}; float()(4.2);
in
Validates if a values is within a given array.
Definition: Krak\Validation\Validators\inArray
Simple Usage:
$validator->make('in:a,b,c')->validate('b');
Standalone Usage:
use function Krak\Validation\Validators\{inArray}; inArray(['a', 'b', 'c'])('b');
integer
Validates that a value is an integer.
Definition: Krak\Validation\Validators\typeInteger()
Simple Usage:
$validator->make('integer')->validate(1);
Standalone Usage:
use function Krak\Validation\Validators\{typeInteger}; typeInteger()(1);
length
Validates that a value's size is exactly the given length.
Definition: Krak\Validation\Validators\length($size)
Simple Usage:
$validator->make('length:3')->validate('abc');
Standalone Usage:
use function Krak\Validation\Validators\{length}; length()('abc');
max
Validates that a value's size is less than or equal to a given max.
Definition: Krak\Validation\Validators\max($max)
Simple Usage:
$validator->make('max:5')->validate(4);
Standalone Usage:
use function Krak\Validation\Validators\{max}; max(5)(4);
min
Validates that a value's size is greater than or equal to a given min.
Definition: Krak\Validation\Validators\min($min)
Simple Usage:
$validator->make('min:2')->validate(3);
Standalone Usage:
use function Krak\Validation\Validators\{min}; min(2)(3);
null
Validates that a value's type is null.
Definition: Krak\Validation\Validators\typeNull()
Simple Usage:
$validator->make('null')->validate(null);
Standalone Usage:
use function Krak\Validation\Validators\{typeNull}; typeNull()(null);
nullable
Validates that a type is null or not. This is typically used in a chain of validators and will stop validation if the value is null or let the validation continue on else.
Definition: Krak\Validation\Validators\nullable()
Simple Usage:
$v = $validator->make('nullable|integer'); $v->validate(null); $v->validate(1);
Standalone Usage:
use function Krak\Validation\Validators\{pipe, nullable, typeInteger}; $v = pipe([nullable(), typeInteger()]); $v(null); $v(1);
number
Validates that a given value is either a float, double, or integer. This is not the same as is_numeric
.
Definition: Krak\Validation\Validators\number()
Simple Usage:
$validator->make('number')->validate(1);
Standalone Usage:
use function Krak\Validation\Validators\{number}; number()(1);
numeric
Validates that a given value is numeric using the is_numeric
function.
Definition: Krak\Validation\Validators\typeNumeric()
Simple Usage:
$validator->make('numeric')->validate('1.5');
Standalone Usage:
use function Krak\Validation\Validators\{typeNumeric}; typeNumeric()('1.5');
optional
Validates that a keyed array is optional and is not required to be present in the array. This validator only make sense within the context of a collection.
Definition: Krak\Validation\Validators\optional()
Simple Usage:
$v = $validator->make([ 'id' => 'optional|integer' ]); $v->validate([]); $v->validate(['id' => 1])
Standalone Usage:
use function Krak\Validation\Validators\{collection, optional, typeInteger, pipe}; $v = collection([ 'id' => pipe([optional(), typeInteger()]) ]); $v([]); $v(['id' => 1]);
regex
Validates that a given value is either a float, double, or integer. This is not the same as is_numeric
.
Definition: Krak\Validation\Validators\regexMatch($regex, $exclude = false)
Simple Usage:
$validator->make('regex:/a+b/')->validate('aaab');
Note defining a regex via the string can be tricky because of how the validation rule parser will validate |
, :
, and ,
. You'll almost always want to call use actual validator itself.
Advanced Usage:
use function Krak\Validation\Validators\{regexMatch}; $validator->make(regexMatch('/(aa|bb)/'))->validate('aa');
Standalone Usage:
use function Krak\Validation\Validators\{regexMatch}; regexMatch('/(aa|bb)/')('aa');
regex_exclude
Exactly like regex
except it matches that the value excludes the specific regular expression.
Definition: Krak\Validation\Validators\regexExclude($regex)
Simple Usage:
$validator->make('regex:/a+b/')->validate('c');
Note defining a regex via the string can be tricky because of how the validation rule parser will validate |
, :
, and ,
. You'll almost always want to call use actual validator itself.
Advanced Usage:
use function Krak\Validation\Validators\{regexExclude}; $validator->make(regexExclude('/(aa|bb)/'))->validate('cc');
Standalone Usage:
use function Krak\Validation\Validators\{regexExclude}; regexExclude('/(aa|bb)/')('cc');
required
Validates that a given value is required in a collection. This validator only makes sense within the context of a collection.
Definition: Krak\Validation\Validators\required()
Simple Usage:
$validator->make([ 'id' => 'required|integer', ])->validate(['id' => 1]);
Standalone Usage:
use function Krak\Validation\Validators\{collection, pipe, typeInteger, required}; collection([ 'id' => pipe([required(), typeInteger()]) ])(['id' => 1]);
string
Validates that a given value is a string.
Definition: Krak\Validation\Validators\typeString()
Simple Usage:
$validator->make('string')->validate('a');
Standalone Usage:
use function Krak\Validation\Validators\{typeString}; typeString()('a');
Doctrine Validation Package
The Doctrine Validation Package defines doctrine related validators.
To enable the doctrine package, you can do the following:
$validation = new Krak\Validation\Kernel(); $validation->withDoctrineValidators(); // only needed for doctrine_entities, doctrine_entity, and doctrine_unique_entity $validation['Doctrine\Common\Persistence\ObjectManager'] = function() { // return a configured entity manager here... }; $validation['Doctrine\DBAL\Connection'] = function() { // return a dbal connection here }; $validation->context([ 'doctrine.model_prefix' => Acme\Model::class, ]);
doctrine_all_exist
Validates that a set of strings or integers all exist in a given table.
Definition: class Krak\Validation\Validators\Doctrine\AllExist($table_name, $field = 'id', $type = 'int')
Simple Usage:
$validator->make('array|all:integer|doctrine_all_exist:users')->validate([1,2,3]);
Standalone Usage:
use Krak\Validation\Validators\Doctrine\AllExist; use function Krak\Validation\Validators\{pipe, typeInteger, forAll}; pipe([forAll(typeInteger), new AllExist('users')])([1,2,3]);
doctrine_entities
Validates that a a set of ORM Entities exist from a unique key. The given entity name is joined with the doctrine.model_prefix
if one is given.
Definition: class Krak\Validation\Validators\Doctrine\Entities($entity_name, $field = 'id')
Simple Usage:
$validator->make('array|all:integer|doctrine_entities:User')->validate([1,2,3]);
Standalone Usage:
use Krak\Validation\Validators\Doctrine\Entities; use function Krak\Validation\Validators\{pipe, typeInteger, forAll}; pipe([forAll(typeInteger), new Entities('User')])([1,2,3]);
doctrine_entity
Validates that an entity exists in the db with the given value.
Definition: class Krak\Validation\Validators\Doctrine\Entity($entity_name, $field = 'id')
Simple Usage:
$validator->make('doctrine_entity:User')->validate(1);
Standalone Usage:
use Krak\Validation\Validators\Doctrine\Entity; (new Entity('User'))->validate(1);
doctrine_exists
Validates that a given value exists in a table in a certain field.
Definition: class Krak\Validation\Validators\Doctrine\Exists($table_name, $field = 'id')
Simple Usage:
$validator->make('doctrine_entity:users')->validate(5);
Standalone Usage:
use Krak\Validation\Validators\Doctrine\Exists; (new Exists('users'))->validate(5);
doctrine_unique
Validates that a given value is unique and doesn't exist in a table in a field.
Definition: class Krak\Validation\Validators\Doctrine\Unique($table_name, $field = 'id')
Simple Usage:
$validator->make('doctrine_unique:users,email')->validate('username@gmail.com');
Standalone Usage:
use Krak\Validation\Validators\Doctrine\Unique; (new Unique('users', 'email'))->validate('username@gmail.com');
doctrine_unique_entity
Validates that a given value exists in a table in a certain field.
Definition: class Krak\Validation\Validators\Doctrine\UniqueEntity($entity_name, $field = 'id')
Simple Usage:
$validator->make('doctrine_unique_entity:User,email')->validate('username@gmail.com');
Standalone Usage:
use Krak\Validation\Validators\Doctrine\UniqueEntity; (new UniqueEntity('User', 'email'))->validate('username@gmail.com');
API
All of the following are defined in the Krak\Validation\Validators
namespace.
collection($validators, $err_on_extra = true)
Validates a map of validators with attribute names mapping to other validators. $err_on_extra
is a flag that will determine whether or not to validate if extra fields are in the input array.
This function will return either a Violation, ViolationCollection, or null depending on the input value.
toSize($value)
Gets the size of a variable. If string, it returns the string length. If array, it returns the count, else it assumes numeric and returns the value itself.