###############
Form Validation
###############
CodeIgniter provides a comprehensive form validation and data prepping
class that helps minimize the amount of code you'll write.
.. contents:: Page Contents
********
Overview
********
Before explaining CodeIgniter's approach to data validation, let's
describe the ideal scenario:
#. A form is displayed.
#. You fill it in and submit it.
#. If you submitted something invalid, or perhaps missed a required
item, the form is redisplayed containing your data along with an
error message describing the problem.
#. This process continues until you have submitted a valid form.
On the receiving end, the script must:
#. Check for required data.
#. Verify that the data is of the correct type, and meets the correct
criteria. For example, if a username is submitted it must be
validated to contain only permitted characters. It must be of a
minimum length, and not exceed a maximum length. The username can't
be someone else's existing username, or perhaps even a reserved word.
Etc.
#. Sanitize the data for security.
#. Pre-format the data if needed (Does the data need to be trimmed? HTML
encoded? Etc.)
#. Prep the data for insertion in the database.
Although there is nothing terribly complex about the above process, it
usually requires a significant amount of code, and to display error
messages, various control structures are usually placed within the form
HTML. Form validation, while simple to create, is generally very messy
and tedious to implement.
************************
Form Validation Tutorial
************************
What follows is a "hands on" tutorial for implementing CodeIgniters Form
Validation.
In order to implement form validation you'll need three things:
#. A :doc:`View <../general/views>` file containing a form.
#. A View file containing a "success" message to be displayed upon
successful submission.
#. A :doc:`controller <../general/controllers>` method to receive and
process the submitted data.
Let's create those three things, using a member sign-up form as the
example.
The Form
========
Using a text editor, create a form called myform.php. In it, place this
code and save it to your application/views/ folder::
My Form
Username
Password
Password Confirm
Email Address
The Success Page
================
Using a text editor, create a form called formsuccess.php. In it, place
this code and save it to your application/views/ folder::
My Form
Your form was successfully submitted!
The Controller
==============
Using a text editor, create a controller called form.php. In it, place
this code and save it to your application/controllers/ folder::
load->helper(array('form', 'url'));
$this->load->library('form_validation');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
else
{
$this->load->view('formsuccess');
}
}
}
Try it!
=======
To try your form, visit your site using a URL similar to this one::
example.com/index.php/form/
If you submit the form you should simply see the form reload. That's
because you haven't set up any validation rules yet.
**Since you haven't told the Form Validation class to validate anything
yet, it returns FALSE (boolean false) by default. ``The run()`` method
only returns TRUE if it has successfully applied your rules without any
of them failing.**
Explanation
===========
You'll notice several things about the above pages:
The form (myform.php) is a standard web form with a couple exceptions:
#. It uses a form helper to create the form opening. Technically, this
isn't necessary. You could create the form using standard HTML.
However, the benefit of using the helper is that it generates the
action URL for you, based on the URL in your config file. This makes
your application more portable in the event your URLs change.
#. At the top of the form you'll notice the following function call:
::
This function will return any error messages sent back by the
validator. If there are no messages it returns an empty string.
The controller (form.php) has one method: ``index()``. This method
initializes the validation class and loads the form helper and URL
helper used by your view files. It also runs the validation routine.
Based on whether the validation was successful it either presents the
form or the success page.
.. _setting-validation-rules:
Setting Validation Rules
========================
CodeIgniter lets you set as many validation rules as you need for a
given field, cascading them in order, and it even lets you prep and
pre-process the field data at the same time. To set validation rules you
will use the ``set_rules()`` method::
$this->form_validation->set_rules();
The above method takes **three** parameters as input:
#. The field name - the exact name you've given the form field.
#. A "human" name for this field, which will be inserted into the error
message. For example, if your field is named "user" you might give it
a human name of "Username".
#. The validation rules for this form field.
#. (optional) Set custom error messages on any rules given for current field. If not provided will use the default one.
.. note:: If you would like the field name to be stored in a language
file, please see :ref:`translating-field-names`.
Here is an example. In your controller (form.php), add this code just
below the validation initialization method::
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
$this->form_validation->set_rules('passconf', 'Password Confirmation', 'required');
$this->form_validation->set_rules('email', 'Email', 'required');
Your controller should now look like this::
load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required',
array('required' => 'You must provide a %s.')
);
$this->form_validation->set_rules('passconf', 'Password Confirmation', 'required');
$this->form_validation->set_rules('email', 'Email', 'required');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
else
{
$this->load->view('formsuccess');
}
}
}
Now submit the form with the fields blank and you should see the error
messages. If you submit the form with all the fields populated you'll
see your success page.
.. note:: The form fields are not yet being re-populated with the data
when there is an error. We'll get to that shortly.
Setting Rules Using an Array
============================
Before moving on it should be noted that the rule setting method can
be passed an array if you prefer to set all your rules in one action. If
you use this approach, you must name your array keys as indicated::
$config = array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => 'required'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'required',
'errors' => array(
'required' => 'You must provide a %s.',
),
),
array(
'field' => 'passconf',
'label' => 'Password Confirmation',
'rules' => 'required'
),
array(
'field' => 'email',
'label' => 'Email',
'rules' => 'required'
)
);
$this->form_validation->set_rules($config);
Cascading Rules
===============
CodeIgniter lets you pipe multiple rules together. Let's try it. Change
your rules in the third parameter of rule setting method, like this::
$this->form_validation->set_rules(
'username', 'Username',
'required|min_length[5]|max_length[12]|is_unique[users.username]',
array(
'required' => 'You have not provided %s.',
'is_unique' => 'This %s already exists.'
)
);
$this->form_validation->set_rules('password', 'Password', 'required');
$this->form_validation->set_rules('passconf', 'Password Confirmation', 'required|matches[password]');
$this->form_validation->set_rules('email', 'Email', 'required|valid_email|is_unique[users.email]');
The above code sets the following rules:
#. The username field be no shorter than 5 characters and no longer than
12.
#. The password field must match the password confirmation field.
#. The email field must contain a valid email address.
Give it a try! Submit your form without the proper data and you'll see
new error messages that correspond to your new rules. There are numerous
rules available which you can read about in the validation reference.
.. note:: You can also pass an array of rules to ``set_rules()``,
instead of a string. Example::
$this->form_validation->set_rules('username', 'Username', array('required', 'min_length[5]'));
Prepping Data
=============
In addition to the validation method like the ones we used above, you
can also prep your data in various ways. For example, you can set up
rules like this::
$this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[5]|max_length[12]');
$this->form_validation->set_rules('password', 'Password', 'trim|required|md5');
$this->form_validation->set_rules('passconf', 'Password Confirmation', 'trim|required|matches[password]');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
In the above example, we are "trimming" the fields, checking for length
where necessary and converting the password to MD5.
**Any native PHP function that accepts one parameter can be used as a
rule, like htmlspecialchars, trim, md5, etc.**
.. note:: You will generally want to use the prepping functions
**after** the validation rules so if there is an error, the
original data will be shown in the form.
Re-populating the form
======================
Thus far we have only been dealing with errors. It's time to repopulate
the form field with the submitted data. CodeIgniter offers several
helper functions that permit you to do this. The one you will use most
commonly is::
set_value('field name')
Open your myform.php view file and update the **value** in each field
using the :php:func:`set_value()` function:
**Don't forget to include each field name in the :php:func:`set_value()`
function calls!**
::
My Form
Username
Password
Password Confirm
Email Address
Now reload your page and submit the form so that it triggers an error.
Your form fields should now be re-populated
.. note:: The :ref:`class-reference` section below
contains methods that permit you to re-populate