Home - rlanvin/php-form GitHub Wiki
This library consists of a Form\Validator
class (only Form
in versions before 2.0). You configure the Form\Validator
class with rules, you give it input values to validate and it'll return validated values and possibly errors.
Default Input values values Rules | | | +-------+ | +-------+ | | | V V V +--------------------+ | Form\Validator | ---> Errors +--------------------+ | V Validated values
The Form\Validator
class can be used to validate anything, whether it's actual values posted by a user through a web form, or GET parameters, API input, etc. Think of it as a proxy between input values and your code.
The Form\Validator
class only takes care of data validation. For example, displaying human readable error messages or generating HTML for the form fields is left up to you. It is, however, very easy to implement on top of it.
// create the form with rules
$form = new Form\Validator([
'name' => ['required', 'trim', 'max_length' => 255],
'email' => ['required', 'email']
]);
if ( $form->validate($_POST) ) {
// $_POST data is valid
$form->getValues(); // returns an array of sanitized values
}
else {
// $_POST data is not valid
$form->getErrors(); // contains the errors
$form->getValues(); // can be used to repopulate the form
}
When creating a Form\Validator
, you need to define a set a rules for each field you want validated. The validation process typically consist of making sure that a field value follows the rules that you defined. Rules may also alter the value during the validation process, for example to cast it or sanitize it.
Rules are processed in order, one after the other.
For the list of all available rules, check this page.
Rules are stored in an assoc array. The key is the rule name and the value is the rule parameter.
For example, to specify that the length of the a field should be between 2 and 255, you would write the following rules array for this field:
['min_length' => 2, 'max_length' => 255]
// or, a more concise way:
['length' => [2,255]]
If the rule doesn't take any parameter, or already has a default parameter, it's possible to omit it. Example:
['required', 'trim']
// is the same as:
['required' => true, 'trim' => " \t\n\r\0\x0B"]
The rule value can be a closure, which will be evaluated during the form validation. A typical situation for this is a form where a field is only required if another field has a certain value. For example, "State" is required if "Country" is "USA". The closure takes the form object as parameter, and returns the parameter expected by the rule.
['state' => ['required' => function($form) { return $form->country == 'USA'; }]]
The entire rules array can also be a closure, which will be evaluated during the form validation. This is useful is more than one rule depends on something else. For example, "State" is required if "Country" is "USA" and it must be in a list.
$form = new Form\Validator([
'country' => ['required'],
'state' => function($form) use ($valid_states) {
return $form->country == 'USA' ? ['required', 'in' => $valid_states] : [];
}
]);
Rules can also consist of another Form\Validator
object (a "sub-form" or "sub-validator"). A typical situation for this is when you want to validate an assoc array, for example two fields coordinates[x]
and coordinates[y]
:
$form = new Form\Validator([
'coordinates' => new Form\Validator([
'x' => ['required', 'integer'],
'y' => ['required', 'integer']
])
]);
More special rules exists to validate complex situations. Please check this page for a complete list.
Rules can be set in the constructor, or using setRules()
or addRules()
methods. Rules can be retrieved with getRules()
. You can pass a field name to setRules()
and getRules()
to set or get rules for a particular field instead of the whole object.
// setting rules in constructor
$form = new Form\Validator([
'name' => ['required', 'trim'],
'email' => ['required', 'trim', 'email']
]);
// setRules will replace any existing rules
$form->setRules([
'name' => ['max_length' => 255]
]);
$form->getRules(); // returns ['name' => ['max_length' => 255]]
// setRules can also be called for a specific field
$form->setRules('name', ['required']);
$form->getRules(); // returns ['name' => ['required' => true]]
// addRules will add the rules to the existing ones instead of replacing them
$form->addRules(['name' => ['max_length' => 255]]);
$form->getRules(); // returns ['name' => ['required' => true, 'max_length' => 255]]
$form->getRules('name'); // returns ['required' => true, 'max_length' => 255]
For nested validators, you can use the HTML syntax to access a the rules of a field.
Example:
$form = new Form\Validator([
'address' => new Form\Validator([
'street' => ['required', 'trim'],
'postcode' => []
])
]);
// get the rules for 'street'
$form->getRules('address['street']);
A Form\Validator
object is a container of values. Before validation, the values are default values (or initial values).
During validation, the default values are merged with the input values. If the validation succeed, you can safely use them. If not, you can use them to repopulate the form, but you shouldn't trust them for any other purpose.
Values can be set and get using traditional method calls, array syntax or object syntax. Example:
// use setValues() to replace all values array
$form->setValues(array('last_name' => 'Wayne'));
$form->getValues(); // return array('last_name' => 'Wayne);
// use addValues() to merge values with existing array
$form->addValues(array('first_name' => 'John'));
$form->getValues(); // return array('first_name' => 'John', 'last_name' => 'Wayne);
// use setValue() to set value of a single field
$form->setValue('first_name', 'Bruce');
$form->first_name = 'Bruce'; // object syntax
$form['first_name'] = 'Bruce'; // array syntax
// use getValue() to get value of a single field
$form->getValue('first_name'); // returns Bruce
$form->first_name; // object syntax
$form['first_name']; // array syntax
For nested validators, you can use the HTML syntax to access a the values of a field.
$form = new Form\Validator([
'address' => new Form\Validator([
'street' => ['required', 'trim'],
'postcode' => []
]),
'colors' => ['each' => ['in' => ['r','g','b']]]
]);
// get the values for 'street'
$form->getValue('address['street']);
// get the values of the Nth color
$form->getValue('color[0]');
The validation process is done with the method validate($values)
that takes input values as parameter. It does two very important things:
- it validates that the input values match the rules, sanitizing when necessary, and returns
true
orfalse
- merge the input values with the existing values in the object, so you can use them later for saving or repopulating the form.
Values must be an assoc array, typically a $_GET
or a $_POST
array, but any array with field name as key and field value as value will do (such as the result of json_decode
if you are working in a API).
During validation, the object will look into the input array for the value of each field. 3 cases can occur.
-
- The field exists as a key in the input array, and has a value. The rules will be applied in order and the value will pass validation or not. Example:
$form = new Form\Validator([
'name' => ['max_length' => 2]
]);
$form->validate(array('name' => 'Foobar')); // false, 'Foobar' is longer that 2
-
- The field exists as a key in the input array, but is considered empty (empty string, empty array or NULL value - 0 and false are not considered empty). If the field is required, validation will fail and no other rule will be checked. Else if the field is not required, validation will succeed, and no other rule will be checked. You can change this behavior, with
allow_empty
validation option.
- The field exists as a key in the input array, but is considered empty (empty string, empty array or NULL value - 0 and false are not considered empty). If the field is required, validation will fail and no other rule will be checked. Else if the field is not required, validation will succeed, and no other rule will be checked. You can change this behavior, with
Example:
$form = new Form\Validator([
'name' => ['required', 'min_length' => 2]
]);
$form->validate(array('name' => '')); // false, name is required
$form = new Form\Validator([
'name' => ['min_length' => 2]
]);
$form->validate(array('name' => '')); // true, name is not required and not provided, so we don't check anything
-
- The fields doesn't exist has a key in the input value. In this case the object will use the default value instead. You can change this behavior with
use_default
validation option. Note: This case cannot happen with a normal web form submit, because the browser will always send the name of the field as key, even if the field is empty.
- The fields doesn't exist has a key in the input value. In this case the object will use the default value instead. You can change this behavior with
Example:
$form = new Form\Validator([
'name' => ['required', 'min_length' => 2]
]);
$form->validate(array()); // false, name is required
$form->setValues(['name' => 'Default name']);
$form->validate(array()); // true, name is required, but a default value exists and is valid
$form->setValues(['name' => 'A']);
$form->validate(array()); // false, the default value for name doesn't match 'min_length'
Options can be set globally for the entire class in the constructor (the second parameter) or using setOptions()
method. They can also be set for one validation only using the second parameter of validate()
.
Check this page for the list of available options.
After failed validation, the errors are stored in the Form\Validator
object as an array. They can be accessed with getErrors()
and getErrors($field)
. Convenience method hasErrors()
and hasErrors($field)
are also available.
The error array has the exact same structure has the rules array, but it contains only the invalid rules.
Example:
$form = new Form\Validator([
'name' => ['required', 'max_length' => 2]
]);
$form->validate(array('name' => 'Foobar'));
var_dump($form->getErrors());
Name is provided, therefore required
passed, but 'Foobar' is longer than 2, therefore max_length
failed. The error array will look like:
[
'name' => [
'max_length' => 2
]
]
For nested validators, you can use the HTML syntax to access a the errors of a field.
$form = new Form\Validator([
'address' => new Form\Validator([
'street' => ['required', 'trim'],
'postcode' => []
])
]);
$form->validate([]);
$form->getErrors();
// [
// 'address' => [
// 'street' => [
// 'required' => true
// ]
// ]
// ]
$form->getErrors('address');
// [
// 'street' => [
// 'required' => true
// ]
// ]
$form->getErrors('address['street']');
// [
// 'required' => true
// ]
Another example, with each
:
$form = new Form\Validator([
'colors' => ['each' => ['in' => ['r','g','b']]]
]);
$form->validate([
'colors' => ['r','v']
]);
$form->getErrors();
// [
// 'colors' => [
// 1 => [
// 'in' => ['r','g','b']
// ]
// ]
// ]
$form->getErrors('colors');
// [
// 1 => [
// 'in' => ['r','g','b']
// ]
// ]
// get the errors of the Nth color
$form->getErrors('colors[1]');
// [
// 'in' => ['r','g','b']
// ]
- List of rules: List of all the rules available
- List of options: List of all the options available
- Validation Cookbook: Recipes for common validation needs