Feature Guide
Namespace import
Respect\Validation is namespaced, but you can make your life easier by importing a single class into your context:
use Respect\Validation\Validator as v;
Simple validation
The Hello World validator is something like this:
$number = 123;
v::numericVal()->validate($number); // true
Chained validation
It is possible to use validators in a chain. Sample below validates a string containing numbers and letters, no whitespace and length between 1 and 15.
$usernameValidator = v::alnum()->noWhitespace()->length(1, 15);
$usernameValidator->validate('alganet'); // true
Validating object attributes
Given this simple object:
$user = new stdClass;
$user->name = 'Alexandre';
$user->birthdate = '1987-07-01';
Is possible to validate its attributes in a single chain:
$userValidator = v::attribute('name', v::stringType()->length(1, 32))
->attribute('birthdate', v::date()->minAge(18));
$userValidator->validate($user); // true
Validating array keys is also possible using v::key()
Note that we used v::stringType()
and v::dateTime()
in the beginning of the validator.
Although is not mandatory, it is a good practice to use the type of the
validated object as the first node in the chain.
Validating array keys and values
Validating array keys into another array is also possible using Key.
If we got the array below:
$data = [
'parentKey' => [
'field1' => 'value1',
'field2' => 'value2'
'field3' => true,
]
];
Using the next combination of rules, we can validate child keys.
v::key(
'parentKey',
v::key('field1', v::stringType())
->key('field2', v::stringType())
->key('field3', v::boolType())
)
->assert($data); // You can also use check() or validate()
Input optional
On oldest versions of Respect\Validation all validators treat input as optional
and accept an empty string input as valid. Even though a useful feature that
caused a lot of troubles for our team and neither was an obvious behavior. Also
there was some people who likes to accept null
as optional value, not only an
empty string.
For that reason all rules are mandatory now but if you want to treat a value as
optional you can use v::optional()
rule:
v::alpha()->validate(''); // false input required
v::alpha()->validate(null); // false input required
v::optional(v::alpha())->validate(''); // true
v::optional(v::alpha())->validate(null); // true
By optional we consider null
or an empty string (''
).
See more on Optional.
Negating rules
You can use the v::not()
to negate any rule:
v::not(v::intVal())->validate(10); // false, input must not be integer
Validator reuse
Once created, you can reuse your validator anywhere. Remember $usernameValidator
?
$usernameValidator->validate('respect'); //true
$usernameValidator->validate('alexandre gaigalas'); // false
$usernameValidator->validate('#$%'); //false
Exception types
Respect\Validation\Exceptions\Exception
:- All exceptions implement this interface;
Respect\Validation\Exceptions\ValidationException
:- Implements the
Respect\Validation\Exceptions\Exception
interface - Thrown when the
check()
fails - All validation exceptions extend this class
- Available methods:
getMessage()
;updateMode($mode)
;updateTemplate($template)
;
Respect\Validation\Exceptions\NestedValidationException
:- Extends the
Respect\Validation\Exceptions\ValidationException
class - Usually thrown when the
assert()
fails - Available methods:
getFullMessage()
;getMessages()
;
Informative exceptions
When something goes wrong, Validation can tell you exactly what's going on. For this,
we use the assert()
method instead of validate()
:
use Respect\Validation\Exceptions\NestedValidationException;
try {
$usernameValidator->assert('really messed up screen#name');
} catch(NestedValidationException $exception) {
echo $exception->getFullMessage();
}
The printed message is exactly this, as a nested Markdown list:
- All of the required rules must pass for "really messed up screen#name"
- "really messed up screen#name" must contain only letters (a-z) and digits (0-9)
- "really messed up screen#name" must not contain whitespace
- "really messed up screen#name" must have a length between 1 and 15
Getting all messages as an array
If you want to get all the messages as an array you can use getMessages()
for
that. The getMessages()
method returns an array with all the messages.
try {
$usernameValidator->assert('really messed up screen#name');
} catch(NestedValidationException $exception) {
print_r($exception->getMessages());
}
The getMessages()
returns an array in which the keys are the name of the
validators, or its reference in case you are using Key or
Attribute rule:
Array
(
[alnum] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9)
[noWhitespace] => "really messed up screen#name" must not contain whitespace
[length] => "really messed up screen#name" must have a length between 1 and 15
)
Custom messages
Getting messages as an array is fine, but sometimes you need to customize them
in order to present them to the user. This is possible using the getMessages()
method as well by passing the templates as an argument:
try {
$usernameValidator->assert('really messed up screen#name');
} catch(NestedValidationException $exception) {
print_r(
$exception->getMessages([
'alnum' => '{{name}} must contain only letters and digits',
'noWhitespace' => '{{name}} cannot contain spaces',
'length' => '{{name}} must not have more than 15 chars',
])
);
}
For all messages, the {{name}}
variable is available for templates. If you do
not define a name it uses the input to replace this placeholder.
The result of the code above will be:
Array
(
[alnum] => "really messed up screen#name" must contain only letters and digits
[noWhitespace] => "really messed up screen#name" cannot contain spaces
[length] => "really messed up screen#name" must not have more than 15 chars
)
Note that getMessage()
will only return a message when the specific validation
in the chain fails.
Validator name
On v::attribute()
and v::key()
, {{name}}
is the attribute/key name. For others,
is the same as the input. You can customize a validator name using:
v::dateTime('Y-m-d')->between('1980-02-02', 'now')->setName('Member Since');
Zend/Symfony validators
It is also possible to reuse validators from other frameworks if they are installed:
$hostnameValidator = v::zend('Hostname')->assert('google.com');
$timeValidator = v::sf('Time')->assert('22:00:01');
Validation methods
We've seen validate()
that returns true or false and assert()
that throws a complete
validation report. There is also a check()
method that returns an Exception
only with the first error found:
use Respect\Validation\Exceptions\ValidationException;
try {
$usernameValidator->check('really messed up screen#name');
} catch(ValidationException $exception) {
echo $exception->getMessage();
}
Message:
"really messed up screen#name" must contain only letters (a-z) and digits (0-9)