This is documentation for Kohana v2.3.x.
Status | Draft |
---|---|
Todo | Add all methods, example form |
The Kohana Validation library is extremely flexible, allowing you to validate any arbitrary array
of data fields, including $_POST
data populated by forms. The library includes built-in rules for frequently required validations and allows you to easily apply custom callback functions or pre-made functions from the Kohana validation helper. The library also enables you to define and apply custom error messages for each field.
The Validation library always processes data in the following order: pre-filters, rules, callbacks then post-filters.
Additional information: Article Tutorial Tutorial with Captcha
The most common data array to validate is $_POST
. Data arrays may be merged and validated as one entity.
// create a new Validation object using the $_POST variable $post = new Validation($_POST); // combine different arrays $post = new Validation(array_merge($_POST, $_FILES)); // using the factory enables method chaining $post = Validation::factory($_POST)->add_rules('field_name', 'required'); // you can also use the $_POST array directly (not recommended) $_POST = new Validation($_POST);
After you instantiate the Validation object you need to add rules to fields. Common rules such as required
are defined by the library. The library is designed to work seamlessly with the valid helper.
Example: These are all equivalent:
$post->add_rules('email', 'required', array('valid','email')); $post->add_rules('email', 'required', 'valid::email'); $post->add_rules('email', 'required', 'email');
All rules are callbacks to functions, the first rule 'required' tests whether the field is required. The second rule tests whether the email address is valid.
Also you can use wildcard or TRUE (rules will apply to all fields):
$post->add_rules('*', 'required');
Note that if you use a wildcard ('*'), the wildcard validation by itself will not work. Working with the first example, you would have to do the following to make the wildcard rule aware of the email field:
$post->add_rules('email', array('valid', 'email')); $post->add_rules('*', 'required');
Filters enable processing of data fields before and after actual validation. By default, a filter is applied to all fields in your data array, but you have the option to specify any number of specific fields for filtering. Any PHP function that accepts and returns a string can be used as a filter. Functions that require additional parameters can not be used as filters.
// uses PHP trim() to remove whitespace from beginning and end of all fields before validation $post->pre_filter('trim'); // runs PHP trim() on just the "title" field $post->pre_filter('trim', 'title'); // runs PHP trim() on "title" and "email" fields $post->pre_filter('trim', 'title', 'email'); // runs a callback on just the "title" field $post->pre_filter(array($this, 'a_custom_filter'), 'title'); // runs PHP ucfirst() on just the "title" field after validation $post->post_filter('ucfirst', 'title');
In addition to rules, you can also add your own callbacks. A callback is simply a method you define to do some custom check on a field. Pass the Validation object to the callback as an argument. The callback should add an error using the add_error()
method if the custom checking fails.
// In this example, we are creating a custom callback function that validates the uniqueness of an email address in the database. // Add the callback, we assume $array is the validation object and the callback is defined in the same controller, hence we use, $this $post->add_callbacks('email', array($this, '_unique_email')); // Define the callback method /* * Callback method that checks for uniqueness of email * * @param Validation $array Validation object * @param string $field name of field being validated */ public function _unique_email(Validation $array, $field) { // check the database for existing records $email_exists = (bool) ORM::factory('user')->where('email', $array[$field])->count_all(); if ($email_exists) { // add error to validation object $array->add_error($field, 'email_exists'); } }
Validating is done with the validate()
method. It first process the pre-filters, then the rules, callbacks and last the post_filters.
If it encounters any errors on an input field, it adds the field name as an array key to the Validation errors array.
If any error was found, boolean FALSE
is returned. if there are no errors, returns TRUE
.
if($post->validate()) { echo 'No validation errors found '; } else { echo 'Validation errors were found '.'<br />'; $errors = $post->errors(); foreach ($errors as $key => $val) { echo $key.' failed rule '.$val.'<br />'; } }
You can use method add_error()
to add an error to the Validation error array.
$post->add_error( 'password', 'pwd_check');
Kohana does not define generic error messages for validation. Error messages should be defined in custom files, created in the application/i18n
folder.
Example: application/i18n/en_US/form_errors.php
A default error condition may also be defined.
$lang = array ( // Change 'field' to the name of the actual field (e.g., 'email'). 'field' => array ( 'required' => 'The name cannot be blank.', 'alpha' => 'Only alphabetic characters are allowed.', 'default' => 'Invalid Input.', ), );
Error messages are retrieved with the errors()
method. By default an array is returned, with the field name as key, and the defined rule as value.
To retrieve customized error messages, an error messages file must be passed to the errors()
method.
$errors = $validation->errors(); // Assuming one rule defined, add_rules('field', 'required') $errors array contains ('field' => 'required') // // Fetch errors using an error messages file $errors = $validation->errors('form_errors') // Assuming a $lang array was created containing $lang = array('field' => array('required' => 'field may not be blank')) // Then $errors will contain an array of ('field' => 'field may not be blank')
Validation input data is accessible via the as_array()
method. This is very useful for re-populating form fields, for example:
// Assume form fields were previously defined in an array eg. $form = array('field_one' => '', 'field_two' => '') // After validation, if errors occurred, we need to re-populate the previously entered information in the form fields. // We use the array helper to overwrite the the original array $form = arr::overwrite($form, $post->as_array());
Rule | Parameter | Description | Example |
---|---|---|---|
required | No | Returns FALSE if form field is empty | |
length | Yes | Returns FALSE if the field is too long or too short | length[1,30] - between 1 and 30 characters longor length[30] - exactly 30 characters long |
depends_on | Yes | Returns FALSE if form field(s) defined in parameter are not filled in | depends_on[field_name] |
matches | Yes | Returns FALSE if field does not match field(s) in parameter | matches[password_again] |
chars | Yes | Returns FALSE if field contains characters not in the parameter | chars[a,b,c,d,1,2,3,4] |
See valid helper for full descriptions and examples.
Rule | Parameter | Description | Example |
---|---|---|---|
No | Returns FALSE if email is not valid | ||
email_domain | No | Returns FALSE if domain of an email does not have valid MX record | |
email_rfc | No | Returns FALSE if email is not rfc822 valid | |
url | No | Returns FALSE if url is not valid | |
ip | Optional | Returns FALSE if ip is not valid | |
credit_card | Yes | Returns FALSE if credit card is not valid | credit_card[mastercard] |
phone | Optional | Returns FALSE if phone number is not a valid length | phone[7,10,11,14] - either 7, 10, 11 or 14 digits long (default is 7, 10 and 11) |
alpha_numeric | Optional | Returns FALSE if form field does not consist only of alphabetical or numeric characters | |
alpha_dash | Optional | Returns FALSE if form field does not consist only of alphabetical, numeric, underscore and dash characters | |
digit | Optional | Returns FALSE if form field does not consist only of digit characters | |
numeric | No | Returns FALSE if form field is not a valid number (positive, negative or decimal) | |
standard_text | No | Returns FALSE if form field is not valid text (letters, numbers, whitespace, dashes, periods and underscores are allowed) | |
decimal | Optional | Returns FALSE if form field is not in proper decimal format Optional parameter is for a specific decimal format | decimal - is any valid decimal formatdecimal[4,2] - is 4 digits and 2 decimal places |
Validate your form in your Controller (application/controllers/welcome.php
): Note: this example uses the Kohana form helper to build the form, but you could also build the form using plain HTML in a separate view and render the form as part of your view. More information about this example.
public function testform() { // setup and initialize your form field names $form = array ( 'name' => '', 'number' => '', 'password' => '', 'code' => '', ); // copy the form as errors, so the errors will be stored with keys corresponding to the form field names $errors = $form; // check, has the form been submitted, if so, setup validation if ($_POST) { // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things $post = new Validation($_POST); // Add some filters $post->pre_filter('trim', TRUE); $post->pre_filter('ucfirst', 'name'); // Add some rules, the input field, followed by a list of checks, carried out in order $post->add_rules('name','required', 'length[3,20]', 'alpha'); $post->add_rules('number', 'required', 'numeric', 'length[3,5]'); $post->add_rules('password', 'required'); // We can write the rules with different syntax, in a line, or individually $post->add_rules('code',array('valid', 'numeric')); $post->add_rules('code','length[3]'); // Add a callback, to validate the password. This is here a method declared in the same controller $post->add_callbacks('password', array($this, 'pwd_check')); // Test to see if things passed the rule checks if ($post->validate()) { // Yes! everything is valid echo 'Form validated and submitted correctly. <br />'; // ok, do whatever ... die(html::anchor('welcome/testform', 'try it again')); } // No! We have validation errors, we need to show the form again, with the errors else { // repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // populate the error fields, if any // We need to already have created an error message file, for Kohana to use // Pass the error message file name to the errors() method $errors = arr::overwrite($errors, $post->errors('form_error_messages')); } } // Display the Form, if there are any errors, they are displayed next to the input field. Uses the Kohana form helper. echo form::open(); echo form::label('name', 'Your Name'); echo form::input('name', ($form['name'])); echo (empty ($errors['name'])) ? '' : $errors['name']; echo '<br />'; echo form::label('number', 'Your Number'); echo form::input('number', $form['number']); echo (empty ($errors['number'])) ? '' : $errors['number']; echo '<br />'; echo form::label('password', 'Password'); echo form::input('password', $form['password']); echo (empty ($errors['password'])) ? '' : $errors['password']; echo '<br />'; echo form::label('code', 'Your code'); echo form::input('code', $form['code']); echo (empty ($errors['code'])) ? '' : $errors['code']; echo '<br />'; echo form::submit('submit', 'Send'); echo '<br />'; echo form::close(); }
Custom callback function in your Controller (application/controllers/welcome.php
):
public function pwd_check(Validation $post) { // If add->rules validation found any errors, get me out of here! if (array_key_exists('password', $post->errors())) return; // only valid password is '123' if ($post->password != '123') { // Add a validation error, this will cause $post->validate() to return FALSE $post->add_error( 'password', 'pwd_check'); } }
Error messages defined in application/i18n/en_US/form_error_messages.php
<?php defined('SYSPATH') or die('No direct access allowed.'); $lang = array ( 'name' => Array ( 'required' => 'The name cannot be blank.', 'alpha' => 'Only alphabetic characters are allowed.', 'length' => 'The name must be between three and twenty letters.', 'default' => 'Invalid Input.', ), 'number' => Array ( 'required' => 'The number cannot be blank.', 'numeric' => 'Only numbers are allowed.', 'length' => 'The number must be between three and five numerals.', 'default' => 'Invalid Input.', ), 'code' => Array ( 'numeric' => 'Only numbers are allowed.', 'length' => 'The code must be exactly three numerals.', 'default' => 'Invalid Input.', ), 'password' => Array ( 'required' => 'You must supply a password.', 'pwd_check' => 'The password is not correct.', 'default' => 'Invalid Input.', ), );
In your controller:
// uses Kohana upload helper $_FILES = Validation::factory($_FILES) ->add_rules('picture', 'upload::valid', 'upload::type[gif,jpg,png]', 'upload::size[1M]'); if ($_FILES->validate()) { // Temporary file name $filename = upload::save('picture'); // Resize, sharpen, and save the image Image::factory($filename) ->resize(100, 100, Image::WIDTH) ->save(DOCROOT.'media/pictures/'.basename($filename).'.jpg'); // Remove the temporary file unlink($filename); // Redirect back to the account page url::redirect('account/information'); }