respect-validation/README.md

282 lines
7.1 KiB
Markdown
Raw Normal View History

2011-02-07 02:35:35 +01:00
Respect Validation
==================
Respect\Validation is the most awesome validation engine ever created for PHP. Featuring:
- Fluent/Chained builders
- Composite validation (nested, grouped and related rules)
- Informative, awesome exceptions
- More than 30 fully tested validators
- PHP 5.3 only
- Possible integration with Zend 2.0 and Symfony 2.0 validators
2011-02-07 15:46:08 +01:00
Roadmap
-------
2011-02-08 19:18:49 +01:00
1. Custom validators (create your own validation rules and exceptions)
2. Validation message improvements (translation, contextualization)
3. PHPDocs for all classes, methods and files
4. End user complete docs
2011-02-07 15:46:08 +01:00
Feature Guide
=============
2011-02-07 02:35:35 +01:00
Namespace import
----------------
2011-02-07 15:46:08 +01:00
Respect\Validation is namespaced, but you can make your life easier by importing
a single class into your context:
<?php
2011-02-07 02:35:35 +01:00
use Respect\Validation\Validator as v;
Simple validation
-----------------
2011-02-07 15:46:08 +01:00
The Hello World validator is something like this:
$number = 123;
v::numeric()->validate($number); //true
2011-02-07 02:35:35 +01:00
Chained validation
------------------
2011-02-07 15:46:08 +01:00
It is possible to group and chain several validators:
2011-02-07 02:35:35 +01:00
//From 1 to 15 non-whitespace alphanumeric characters
$validUsername = v::alnum()
->noWhitespace()
->length(1,15);
2011-02-07 02:35:35 +01:00
$validUsername->validate('alganet'); //true
2011-02-07 02:35:35 +01:00
Validating object attributes
----------------------------
2011-02-07 15:46:08 +01:00
You can validate attributes of objects or keys of arrays and its values too:
$validUser = v::attribute('username', $validUsername) //reusing!
->attribute('birthdate', v::date('Y-m-d'));
2011-02-07 02:35:35 +01:00
$user = new \stdClass;
$user->username = 'alganet';
2011-02-07 02:35:35 +01:00
$user->birthdate = '1987-07-01';
$validUser->validate($user); //true
2011-02-07 02:35:35 +01:00
Validator reuse (works on nested, big validators too!)
------------------------------------------------------
2011-02-07 15:46:08 +01:00
Once created, you can reuse your validator anywhere:
$validUsername->validate('respect'); //true
$validUsername->validate('alexandre gaigalas'); //false
$validUsername->validate('#$%'); //false
2011-02-07 02:35:35 +01:00
Cool, informative exceptions
----------------------------
2011-02-07 15:46:08 +01:00
Respect\Validation produces a tree of validation messages that reflects
the groups, nests and composite validators you declared. The following code:
2011-02-07 02:35:35 +01:00
try {
$validUsername->assert('really messed up screen#name');
2011-02-07 02:35:35 +01:00
} catch(\InvalidArgumentException $e) {
echo $e->getFullMessage();
}
Produces this message:
\-None of 3 required rules passed
|-"really messed up screen#name" does not contain only letters, digits and "_"
|-"really messed up screen#name" contains whitespace
\-"really messed up screen#name" length is not between 1 and 15
2011-02-07 15:46:08 +01:00
Validation Methods
------------------
There are three different ways to validate something:
$validUsername->validate('alganet'); //returns true or false (quicker)
$validUsername->check('alganet'); //throws only the first error found (quicker)
$validUsername->assert('alganet'); //throws all of the errors found (slower)
2011-02-07 02:35:35 +01:00
Message finding on nested Exceptions
------------------------------------
2011-02-07 15:46:08 +01:00
Nested exceptions are cool, but sometimes you need to retrieve a single message
from the validator. In these cases you can use the findRelated() method. Consider
the following scenario:
$validBlogPost = v::object()
->attribute('title', v::string()->length(1,32))
->attribute('author', $validUser) //reuse!
->attribute('date', v::date())
->attribute('text', v::string());
$blogPost = new \stdClass;
$blogPost->author = clone $validUser;
$blogPost->author->username = '# invalid #';
2011-02-07 15:46:08 +01:00
Then, the following validation code:
2011-02-07 02:35:35 +01:00
try {
$validBlogPost->assert($blogPost);
2011-02-07 02:35:35 +01:00
} catch (\InvalidArgumentException $e) {
echo $e->findRelated('author', 'username', 'noWhitespace')->getMainMessage();
2011-02-07 02:35:35 +01:00
}
Finds the specific noWhitespace message inside author->username and prints it:
>"# invalid #" contains whitespace
2011-02-07 02:35:35 +01:00
Using Zend and/or Symfony validators
------------------------------------
2011-02-07 15:46:08 +01:00
It is also possible to reuse validators from other frameworks (you need to put them
in your autoload routines):
2011-02-07 02:35:35 +01:00
$validHostName = v::zend('hostname')->assert('google.com');
$validTime = v::sf('time')->assert('22:00:01');
2011-02-07 15:46:08 +01:00
Quick Reference
==============
2011-02-07 02:35:35 +01:00
2011-02-07 15:46:08 +01:00
A quick, possibly incomplete, list of validators and use reference:
Alphanumeric:
v::alnum()->assert('abc 123');
v::alnum('_|')->assert('a_bc _1|23');
Alpha chars:
v::alpha()->assert('ab c');
v::alpha('.')->assert('a. b.c');
Check if it is an array (works on every Traversable, Countable ArrayAccess):
v::arr()->assert(array());
v::arr()->assert(new \ArrayObject);
An attribute of an object ant its value:
$myObject = new \stdClass;
$myObject->foo = "bar";
v::attribute("foo", v::string())->assert($myObject);
Between (works on numbers, digits and dates):
v::between(5, 15)->assert(10);
v::between('a', 'f')->assert('b');
A value after a function call (works with closures):
v::call('implode', v::int())->assert(array(1, 2, 3, 4));
Validates using the return of a callback:
v::callback('is_string')->assert('something');
Dates and date formats:
v::date('Y-m-d')->assert('2010-10-10');
v::date()->assert('Jan 10 2008');
Strings with digits:
2011-02-07 02:35:35 +01:00
2011-02-07 15:46:08 +01:00
v::digits()->assert('02384');
2011-02-07 02:35:35 +01:00
2011-02-07 15:46:08 +01:00
Iterates and validates each element:
v::each(v::hexa())->assert(array('AF', 'D1', '09'));
Check for equality:
v::equals('foobar')->assert('foobar');
Float numbers
v::float()->assert(1.5);
Hexadecimals:
v::hexa()->assert('FAFAF');
Checks if a value is inside a set:
v::in(array(1, 1, 2, 3, 5, 8))->assert(5);
Checks if an object is instance of a specific class or interface:
v::instance('\stdClass')->assert(new \stdClass);
Integer numbers:
v::int()->assert(1548);
IP addresses:
v::ip()->assert('200.226.220.222');
Length of strings, arrays or everything Countable:
v::length(5, 10)->assert('foobar');
v::length(5, 10)->assert(array(1, 2, 3, 4, 5));
Max and Min:
v::max(5)->assert(3);
v::min(5)->assert(7);
Positive and Negative:
v::negative()->assert(-5);
v::positive()->assert(3);
Whitespace, empty and null
v::noWhitespace()->assert('abc');
v::notEmpty()->assert('aaa');
v::nullValue()->assert(null);
Numeric values of all kinds:
v::numeric()->assert(1.56e-5);
Objects:
v::object()->assert(new \DateTime());
Regex evaluations:
v::regex('^[a-f]+$')->assert('abcdef');
Strings:
v::string()->assert('Hello World');
AllOf (checks all validators inside a composite):
v::allOf(
v::string(), //any string v::length(5, 20), //between 5 and 20 chars
v::noWhitespace() //no whitespace allowed
)->assert('alganet');
v::string()
->length(5, 20)
->noWhitespace()
->assert('alganet');
OneOf (checks for one valid inside of a composite):
$v = v::oneOf(
v::int()->positive(), //positive integer or;
v::float()->negative(), //negative float or;
v::nullValue() //null
);
$v->assert(null); //true
$v->assert(12); //true
$v->assert(-1.1); //true