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 Roadmap ------- 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 Feature Guide ============= Namespace import ---------------- Respect\Validation is namespaced, but you can make your life easier by importing a single class into your context: validate($number); //true Chained validation ------------------ It is possible to group and chain several validators: //From 1 to 15 non-whitespace alphanumeric characters $validUsername = v::alnum() ->noWhitespace() ->length(1,15); $validUsername->validate('alganet'); //true Validating object attributes ---------------------------- 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')); $user = new \stdClass; $user->username = 'alganet'; $user->birthdate = '1987-07-01'; $validUser->validate($user); //true Validator reuse (works on nested, big validators too!) ------------------------------------------------------ Once created, you can reuse your validator anywhere: $validUsername->validate('respect'); //true $validUsername->validate('alexandre gaigalas'); //false $validUsername->validate('#$%'); //false Cool, informative exceptions ---------------------------- Respect\Validation produces a tree of validation messages that reflects the groups, nests and composite validators you declared. The following code: try { $validUsername->assert('really messed up screen#name'); } 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 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) Message finding on nested Exceptions ------------------------------------ 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 #'; Then, the following validation code: try { $validBlogPost->assert($blogPost); } catch (\InvalidArgumentException $e) { echo $e->findRelated('author', 'username', 'noWhitespace')->getMainMessage(); } Finds the specific noWhitespace message inside author->username and prints it: >"# invalid #" contains whitespace Using Zend and/or Symfony validators ------------------------------------ It is also possible to reuse validators from other frameworks (you need to put them in your autoload routines): $validHostName = v::zend('hostname')->assert('google.com'); $validTime = v::sf('time')->assert('22:00:01'); Quick Reference ============== 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: v::digits()->assert('02384'); 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