A new PHPixie Validation module is available. It allows you to easily validate user input and present the user with a list of errors he made while filling a form. Let’s try validating form POST data.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$validate=Validate::factory(%this->request->post());
$validate
//Username must be filled
->rule('username','filled')
//Password must be filled and at least 5 characters long
->rule('password',array(
'filled',
array('min_length',5)
));
//Check if the input is valid
if($validate->valid()){
echo 'Thanks!';
}else {
//Get the array of errors for each field
print_r($validate->errors());
}
By default all fields are optional, so if don’t add a ‘filled’ rule and the field is empty it will always be considered valid. The rule() expects three parameters: field name, an array of rules applied to this field, conditions that must be met for this rule to apply. Let’s take a closer look at the second parameter:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//If you just need to add a single rule that doesn't require
//any additional parameters you can just pass it's name
$validate->rule('username','filled');
//Otherwise you pass an array
$validate->rule('username',array(
array('min_length',7);
));
//If the rule you wish to use requires more then one parameter
//you have to pass them as array
$validate->rule('age',array(
array('between',array(13,60));
));
//If you wish the rule NOT to match place a '!' before it's name
//like this:
$validate->rule('username','!filled');
//It will become useful later on
If you call rule() multiple times passing the same field such rule sets will have an OR logic, so if any of them matches a field is considered valid:
1
2
3
//this way 'contact' can be either a url or an email
$validate->rule('contact','url');
$validate->rule('contact','email');
This becomes much more useful when combined with conditional rules. Conditions follow the same structure as a standart result set. The ruleset is only applied if those conditions are met.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//Height must be between 3 and 7 inches if
//type is 'fairy'
$validate->rule('height',array(
array('between',array(3,7))
),array(
array('type',array(
array('equals','fairy');
))
)
);
//Or it must be between 1 and 2 inches if
//type is 'pixie'
$validate->rule('height',array(
array('between',array(1,2))
),array(
array('type',array(
array('equals','pixie');
))
)
);
Of course you always could wrap those rules inside and if statement and just apply them whenever you would need them. But the largest drawback of such an approach would be that it would be far less portable. This way you could set you could set your Validate object once and then use it to validate different arrays of data like this:
1
2
3
//Validate new data
$validate->inputs($data);
print_r($validate->errors());
Lets now look at how the error array looks:
1
2
3
4
5
6
7
8
9
10
11
12
13
Array
(
[username] => Array
(
[0] => filled
)
[password] => Array
(
[0] => min_length
)
)
This would mean that username was not filled and password didn’t meet minimum length. You can set other identifiers for a rule like this:
1
2
3
4
5
6
//This would return a password_length_not_met
//error inside the errors array
$validate->rule('password',array(
'filled',
array('min_length',6,'password_length_not_met')
));
Such identifiers are very useful for things like translations etc. You can find the full set of allowed rules and their parameters as static methods of the Validate Class and you are free to add your own rules using the validate.php config file like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
// /modules/validate/config/validate.php
<?php
return array(
'rules' => array(
//This would check if the value consists of uppercase
//letters only
'uppercase' => function($val) {
return (bool)preg_match('#[A-Z]#',$val);
}
)
);
If you just need to use a function a single time and don’t feel like it’s important enough to be added to the config file, you can always use the func rule like this:
1
2
3
4
5
6
$validate->rule('access_token',array(
'filled',
array('func',function($val){
//Returns either true or false
},'token_invalid')
));