2017 © Pedro Peláez
 

library validation

Functional validation library

image

krak/validation

Functional validation library

  • Sunday, March 18, 2018
  • by ragboyjr
  • Repository
  • 1 Watchers
  • 1 Stars
  • 1,185 Installations
  • PHP
  • 2 Dependents
  • 1 Suggesters
  • 0 Forks
  • 2 Open issues
  • 17 Versions
  • 4 % Grown

The README.md

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 alpha alpha_num array
between boolean date digits
double email exists float
in integer length max
min null nullable number
numeric optional regex regex_exclude
required string

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)

doctrine_all_exist doctrine_entities doctrine_entity doctrine_exists
doctrine_unique doctrine_unique_entity

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)

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., (*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)

The Versions

12/09 2017
11/06 2016
21/05 2016
31/07 2015
06/07 2015