Krak Validation
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., (*1)
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., (*2)
Installation
Install with composer at krak/validation
, (*3)
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:, (*4)
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., (*5)
Validators implement the following signature:, (*6)
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., (*7)
Violations
Creating violations is easy with the violate
or violations
function. For most validators, you'll simply be creating one violation., (*8)
<?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., (*9)
Throwing Violations
Once you have a violation or a violation collection, you can optionally throw them as exceptions to be handled upstream., (*10)
<?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., (*11)
$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:, (*12)
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., (*13)
Creating a Validation Package
To create a validation package, you need to extend the ValidationPackage
interface., (*14)
interface ValidationPackage
{
public function withValidation(Kernel $validation);
}
From there, you can configure the validation kernel any which way you need., (*15)
Typically, you'll just use the validators
, messages
, and aliases
methods to add keyed validations and corresponding methods or aliases., (*16)
An example Validation Package would look like:, (*17)
<?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:, (*18)
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., (*19)
all
Validates an array with the given validator. If any element in the array fails the validation, a violation will be returned., (*20)
Definition: Krak\Validation\Validators\forAll($validator)
, (*21)
Simple Usage:, (*22)
$validator->make('all:integer')->validate([1,2,3]);
Advanced Usage:, (*23)
use function Krak\Validation\Validators\{forAll};
$validator->make(forAll('integer|between:1,3'))->validate([1,2,3])
Standalone Usage:, (*24)
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., (*25)
Definition: Krak\Validation\Validators\alpha()
, (*26)
Simple Usage:, (*27)
$validator->make('alpha')->validate('abc');
Standalone Usage:, (*28)
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., (*29)
Definition: Krak\Validation\Validators\alphaNum()
, (*30)
Simple Usage:, (*31)
$validator->make('alpah_num')->validate('abc123');
Standalone Usage:, (*32)
use function Krak\Validation\Validators\{alphaNum};
alphaNum()('abc123');
array
Verifies that the value is an array using is_array
., (*33)
Definition: Krak\Validation\Validators\typeArray()
, (*34)
Simple Usage:, (*35)
$validator->make('array')->validate();
Standalone Usage:, (*36)
use function Krak\Validation\Validators\{typeArray};
typeArray()([]);
between
Validates a value's size is between two values inclusively., (*37)
Definition: Krak\Validation\Validators\between($min, $max)
, (*38)
Simple Usage:, (*39)
$validator->make('between:1,2')->validate(2);
Standalone Usage:, (*40)
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., (*41)
Definition: Krak\Validation\Validators\typeBoolean()
, (*42)
Simple Usage:, (*43)
$validator->make('boolean')->validate(true);
Standalone Usage:, (*44)
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., (*45)
Definition: Krak\Validation\Validators\date()
, (*46)
Simple Usage:, (*47)
$validator->make('date')->validate('2017-08-11');
Standalone Usage:, (*48)
use function Krak\Validation\Validators\{date};
date()('2017-08-11');
digits
Validates a string is of type digits using the ctype_digits
function., (*49)
Definition: Krak\Validation\Validators\digits()
, (*50)
Simple Usage:, (*51)
$validator->make('digits')->validate('123');
Standalone Usage:, (*52)
use function Krak\Validation\Validators\{digits};
digits()('123');
double
Validates a value is a double using is_double
., (*53)
Definition: Krak\Validation\Validators\double()
, (*54)
Simple Usage:, (*55)
$validator->make('double')->validate(4.2);
Standalone Usage:, (*56)
use function Krak\Validation\Validators\{double};
double()(4.2);
email
Validates that a string matches an email regex., (*57)
Definition: Krak\Validation\Validators\regexEmail()
, (*58)
Simple Usage:, (*59)
$validator->make('email')->validate('username@gmail.com');
Standalone Usage:, (*60)
use function Krak\Validation\Validators\{regexEmail};
regexEmail()('username@gmail.com');
exists
Alias of required
., (*61)
float
Validates a value is a float using is_float
., (*62)
Definition: Krak\Validation\Validators\float()
, (*63)
Simple Usage:, (*64)
$validator->make('float')->validate(4.2);
Standalone Usage:, (*65)
use function Krak\Validation\Validators\{float};
float()(4.2);
in
Validates if a values is within a given array., (*66)
Definition: Krak\Validation\Validators\inArray
, (*67)
Simple Usage:, (*68)
$validator->make('in:a,b,c')->validate('b');
Standalone Usage:, (*69)
use function Krak\Validation\Validators\{inArray};
inArray(['a', 'b', 'c'])('b');
integer
Validates that a value is an integer., (*70)
Definition: Krak\Validation\Validators\typeInteger()
, (*71)
Simple Usage:, (*72)
$validator->make('integer')->validate(1);
Standalone Usage:, (*73)
use function Krak\Validation\Validators\{typeInteger};
typeInteger()(1);
length
Validates that a value's size is exactly the given length., (*74)
Definition: Krak\Validation\Validators\length($size)
, (*75)
Simple Usage:, (*76)
$validator->make('length:3')->validate('abc');
Standalone Usage:, (*77)
use function Krak\Validation\Validators\{length};
length()('abc');
max
Validates that a value's size is less than or equal to a given max., (*78)
Definition: Krak\Validation\Validators\max($max)
, (*79)
Simple Usage:, (*80)
$validator->make('max:5')->validate(4);
Standalone Usage:, (*81)
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., (*82)
Definition: Krak\Validation\Validators\min($min)
, (*83)
Simple Usage:, (*84)
$validator->make('min:2')->validate(3);
Standalone Usage:, (*85)
use function Krak\Validation\Validators\{min};
min(2)(3);
null
Validates that a value's type is null., (*86)
Definition: Krak\Validation\Validators\typeNull()
, (*87)
Simple Usage:, (*88)
$validator->make('null')->validate(null);
Standalone Usage:, (*89)
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., (*90)
Definition: Krak\Validation\Validators\nullable()
, (*91)
Simple Usage:, (*92)
$v = $validator->make('nullable|integer');
$v->validate(null);
$v->validate(1);
Standalone Usage:, (*93)
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
., (*94)
Definition: Krak\Validation\Validators\number()
, (*95)
Simple Usage:, (*96)
$validator->make('number')->validate(1);
Standalone Usage:, (*97)
use function Krak\Validation\Validators\{number};
number()(1);
numeric
Validates that a given value is numeric using the is_numeric
function., (*98)
Definition: Krak\Validation\Validators\typeNumeric()
, (*99)
Simple Usage:, (*100)
$validator->make('numeric')->validate('1.5');
Standalone Usage:, (*101)
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., (*102)
Definition: Krak\Validation\Validators\optional()
, (*103)
Simple Usage:, (*104)
$v = $validator->make([
'id' => 'optional|integer'
]);
$v->validate([]);
$v->validate(['id' => 1])
Standalone Usage:, (*105)
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
., (*106)
Definition: Krak\Validation\Validators\regexMatch($regex, $exclude = false)
, (*107)
Simple Usage:, (*108)
$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., (*109)
Advanced Usage:, (*110)
use function Krak\Validation\Validators\{regexMatch};
$validator->make(regexMatch('/(aa|bb)/'))->validate('aa');
Standalone Usage:, (*111)
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., (*112)
Definition: Krak\Validation\Validators\regexExclude($regex)
, (*113)
Simple Usage:, (*114)
$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., (*115)
Advanced Usage:, (*116)
use function Krak\Validation\Validators\{regexExclude};
$validator->make(regexExclude('/(aa|bb)/'))->validate('cc');
Standalone Usage:, (*117)
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., (*118)
Definition: Krak\Validation\Validators\required()
, (*119)
Simple Usage:, (*120)
$validator->make([
'id' => 'required|integer',
])->validate(['id' => 1]);
Standalone Usage:, (*121)
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., (*122)
Definition: Krak\Validation\Validators\typeString()
, (*123)
Simple Usage:, (*124)
$validator->make('string')->validate('a');
Standalone Usage:, (*125)
use function Krak\Validation\Validators\{typeString};
typeString()('a');
Doctrine Validation Package
The Doctrine Validation Package defines doctrine related validators., (*126)
To enable the doctrine package, you can do the following:, (*127)
$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., (*128)
Definition: class Krak\Validation\Validators\Doctrine\AllExist($table_name, $field = 'id', $type = 'int')
, (*129)
Simple Usage:, (*130)
$validator->make('array|all:integer|doctrine_all_exist:users')->validate([1,2,3]);
Standalone Usage:, (*131)
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., (*132)
Definition: class Krak\Validation\Validators\Doctrine\Entities($entity_name, $field = 'id')
, (*133)
Simple Usage:, (*134)
$validator->make('array|all:integer|doctrine_entities:User')->validate([1,2,3]);
Standalone Usage:, (*135)
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., (*136)
Definition: class Krak\Validation\Validators\Doctrine\Entity($entity_name, $field = 'id')
, (*137)
Simple Usage:, (*138)
$validator->make('doctrine_entity:User')->validate(1);
Standalone Usage:, (*139)
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., (*140)
Definition: class Krak\Validation\Validators\Doctrine\Exists($table_name, $field = 'id')
, (*141)
Simple Usage:, (*142)
$validator->make('doctrine_entity:users')->validate(5);
Standalone Usage:, (*143)
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., (*144)
Definition: class Krak\Validation\Validators\Doctrine\Unique($table_name, $field = 'id')
, (*145)
Simple Usage:, (*146)
$validator->make('doctrine_unique:users,email')->validate('username@gmail.com');
Standalone Usage:, (*147)
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., (*148)
Definition: class Krak\Validation\Validators\Doctrine\UniqueEntity($entity_name, $field = 'id')
, (*149)
Simple Usage:, (*150)
$validator->make('doctrine_unique_entity:User,email')->validate('username@gmail.com');
Standalone Usage:, (*151)
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., (*152)
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., (*153)
This function will return either a Violation, ViolationCollection, or null depending on the input value., (*154)
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., (*155)