As a web application developer, form validation is a crucial part of your work, and it should not be underrated as it could lead to security flaws in your application. You should consider it a must if you're striving to provide a professional end user experience.
In this article, we'll go through the built-in form validation library in the CodeIgniter framework.
Here are the highlights of today's article:
- Basic form validation
- Cascading and prepping
- Custom error messages
- Custom validation callback
- Validation configuration
Go Through Basic Validation Rules
In this section, we'll go through the basic form validation concepts in CodeIgniter.
As a part of that, we need to create controller and view files. The controller file loads the validation library and runs validation rules against the submitted form data. The view file holds the form XHTML code, and we'll keep it simple for our needs.
Let's go ahead and create these two files.
Create the controller file application/controllers/Validation.php
with the following contents.
<?php // application/controllers/Validation.php defined('BASEPATH') OR exit('No direct script access allowed'); class Validation extends CI_Controller { public function __construct() { parent::__construct(); // load form and url helpers $this->load->helper(array('form', 'url')); // load form_validation library $this->load->library('form_validation'); } public function basic() { // basic required field $this->form_validation->set_rules('text_field', 'Text Field One', 'required'); // basic required field with minimum length $this->form_validation->set_rules('min_text_field', 'Text Field Two', 'required|min_length[8]'); // basic required field with maximum length $this->form_validation->set_rules('max_text_field', 'Text Field Three', 'required|max_length[20]'); // basic required field with exact length $this->form_validation->set_rules('exact_text_field', 'Text Field Four', 'required|exact_length[12]'); // basic required field but alphabets only $this->form_validation->set_rules('alphabets_text_field', 'Text Field Five', 'required|alpha'); // basic required field but alphanumeric only $this->form_validation->set_rules('alphanumeric_text_field', 'Text Field Six', 'required|alpha_numeric'); // basic email field with email validation $this->form_validation->set_rules('valid_email_field', 'Email Field', 'required|valid_email'); // password field with confirmation field matching $this->form_validation->set_rules('password_field', 'Password One', 'required'); $this->form_validation->set_rules('password_confirmation_field', 'Password Confirmation Field', 'required|matches[password_field]'); // basic required field with IPv4 validation $this->form_validation->set_rules('valid_ip_field', 'Valid IP Field', 'required|valid_ip[ipv4]'); if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } } public function cascade() { // basic required field with cascaded rules $this->form_validation->set_rules('text_field', 'Text Field One', 'required|alpha|min_length[8]|max_length[20]'); if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } } public function prep() { // basic required field with trim prepping applied $this->form_validation->set_rules('min_text_field', 'Text Field Two', 'trim|required|min_length[8]'); if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } } public function custom_message() { // basic required field with trim prepping applied $this->form_validation->set_rules('alphabets_text_field', 'Text Field Five', 'required|alpha', array('required'=>'Please enter Text Field Five!','alpha'=>'Only alphabets please!')); if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } } public function custom_rule() { // basic required field with trim prepping applied $this->form_validation->set_rules('text_field', 'Text Field Five', 'callback_custom_validation'); if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } } public function custom_validation($field_value) { if ($field_value == '' || $field_value == 'demo') { $this->form_validation->set_message('custom_validation', "Come on, don't act like spammer!"); return FALSE; } else { return TRUE; } } public function configuration() { // if you pass group id, only elements in that group will be validated // $this->form_validation->run('group_one') if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } } }
Next, create the view file application/views/validate_form.php
as shown below.
<html> <head> <title>Form Validation Example</title> <style> .field_title{font-size: 13px;font-family:Arial;width: 300px;margin-top: 10px} .form_error{font-size: 13px;font-family:Arial;color:red;font-style:italic} </style> </head> <body> <div class="form_error"> <?php echo validation_errors(); ?> </div> <?php echo form_open(); ?> <h2>Form Validation Example</h2> <div> <div class="field_title">Text Field One (Required)</div> <input type="text" name="text_field" value="<?php echo set_value('text_field'); ?>" size="30" /> </div> <div> <div class="field_title">Text Field Two (Minimum length)</div> <input type="text" name="min_text_field" value="<?php echo set_value('min_text_field'); ?>" size="30" /> </div> <div> <div class="field_title">Text Field Three (Maximum length)</div> <input type="text" name="max_text_field" value="<?php echo set_value('max_text_field'); ?>" size="30" /> </div> <div> <div class="field_title">Text Field Four (Exact length)</div> <input type="text" name="exact_text_field" value="<?php echo set_value('exact_text_field'); ?>" size="30" /> </div> <div> <div class="field_title">Text Field Five (Alphabets only)</div> <input type="text" name="alphabets_text_field" value="<?php echo set_value('alphabets_text_field'); ?>" size="30" /> </div> <div> <div class="field_title">Text Field Six (Alphanumeric only)</div> <input type="text" name="alphanumeric_text_field" value="<?php echo set_value('alphanumeric_text_field'); ?>" size="30" /> </div> <div> <div class="field_title">Email Field</div> <input type="text" name="valid_email_field" value="<?php echo set_value('valid_email_field'); ?>" size="30" /> </div> <div> <div class="field_title">Password Field</div> <input type="password" name="password_field" value="" size="30" /> </div> <div> <div class="field_title">Password Confirmation Field</div> <input type="password" name="password_confirmation_field" value="" size="30" /> </div> <div> <div class="field_title">IP Field</div> <input type="text" name="valid_ip_field" value="<?php echo set_value('valid_ip_field'); ?>" size="30" /> </div> <div class="field_title"> <input type="submit" value="Submit" /> </div> </form> </body> </html>
With this setup, you should see a form when you run http://your-codeigniter-site/validation/basic in your browser. Try to submit it without filling any of the form fields, and you'll see the list of error messages! Don't worry if you don't understand how it works altogether as we'll go through every piece of code in detail.
The story starts with the __construct
method.
public function __construct() { parent::__construct(); // load form and url helpers $this->load->helper(array('form', 'url')); // load form_validation library $this->load->library('form_validation'); }
I always prefer to load common libraries and helpers in the constructor of the controller itself as it's a nice habit to avoid code duplication elsewhere in controller methods. That's exactly what we've done above—we load the form
and url
helpers so that we can use the utility methods provided by those helpers throughout the rest of the application.
Next, we load the form validation library so that it allows us to bind form validation rules on form elements, as we'll see in the very next section.
Let's go through the code of the basic
method. What does this method do? If you call it with the GET
method, it'll display the form, and if it was called using the POST
method, it applies validation rules on the submitted data and displays error messages, if any, along with the form.
public function basic() { // basic required field $this->form_validation->set_rules('text_field', 'Text Field One', 'required'); // basic required field with minimum length $this->form_validation->set_rules('min_text_field', 'Text Field Two', 'required|min_length[8]'); // basic required field with maximum length $this->form_validation->set_rules('max_text_field', 'Text Field Three', 'required|max_length[20]'); // basic required field with exact length $this->form_validation->set_rules('exact_text_field', 'Text Field Four', 'required|exact_length[12]'); // basic required field but alphabets only $this->form_validation->set_rules('alphabets_text_field', 'Text Field Five', 'required|alpha'); // basic required field but alphanumeric only $this->form_validation->set_rules('alphanumeric_text_field', 'Text Field Six', 'required|alpha_numeric'); // basic email field with email validation $this->form_validation->set_rules('valid_email_field', 'Email Field', 'required|valid_email'); // password field with confirmation field matching $this->form_validation->set_rules('password_field', 'Password One', 'required'); $this->form_validation->set_rules('password_confirmation_field', 'Password Confirmation Field', 'required|matches[password_field]'); // basic required field with IPv4 validation $this->form_validation->set_rules('valid_ip_field', 'Valid IP Field', 'required|valid_ip[ipv4]'); if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } }
As we've already loaded the form validation library in the constructor, you can access it using the $this->form_validation
convention.
The set_rules
method is used to bind a validation rule on a form field. Generally, it takes three arguments:
- The first argument is the name of a form field.
- The second argument is a label that is used to reference a form field while displaying the error message for that field.
- The third argument is the rule that you want to apply on a form field. The form validation library comes with lots of built-in rules that you could use already.
Let's go through some of these rules as we've used them in the basic method.
One of the most frequently used rules is the required
rule, which makes a form field compulsory.
// basic required field $this->form_validation->set_rules('text_field', 'Text Field One', 'required');
Next, if you want to make a form field of a certain length, you can use the min_length
and max_length
rules.
// basic required field with minimum length $this->form_validation->set_rules('min_text_field', 'Text Field Two', 'required|min_length[8]'); // basic required field with maximum length $this->form_validation->set_rules('max_text_field', 'Text Field Three', 'required|max_length[20]');
The first one makes sure that the min_text_field
form field is a compulsory field and the user must enter at least eight characters in it. The second one puts a limit on the maximum characters that can be entered in the max_text_field
text field, in addition to making it a compulsory field.
You may have noticed that we've used the |
operator to apply multiple rules at once. It's called cascading, and we'll get back to it later.
On the other hand, if you want to make a form field of an exact length, you can use the exact_length
rule.
// basic required field with exact length $this->form_validation->set_rules('exact_text_field', 'Text Field Four', 'required|exact_length[12]');
What if you want to validate a form field to alphabets or alphanumeric only?
// basic required field but alphabets only $this->form_validation->set_rules('alphabets_text_field', 'Text Field Five', 'required|alpha'); // basic required field but alphanumeric only $this->form_validation->set_rules('alphanumeric_text_field', 'Text Field Six', 'required|alpha_numeric');
The next candidate is the email validation.
// basic email field with email validation $this->form_validation->set_rules('valid_email_field', 'Email Field', 'required|valid_email');
Next, the matches
rule allows you to compare the value of a form field with another form field's value. The best example of this is the password field, which must match the password confirmation field when you submit the form.
// password field with confirmation field matching rule $this->form_validation->set_rules('password_field', 'Password One', 'required'); $this->form_validation->set_rules('password_confirmation_field', 'Password Confirmation Field', 'required|matches[password_field]');
The last example in our basic method is about validating the IP address.
The valid_ip
rule validates the IP address against the first argument passed. In the following example, we're only looking for ipv4 type of IP addresses!
// basic required field with IPv4 validation $this->form_validation->set_rules('valid_ip_field', 'Valid IP Field', 'required|valid_ip[ipv4]');
So that's it as far as basic validation is concerned in CodeIgniter.
How Cascading and Prepping Works
In this section, we'll explore cascading and prepping, which allow you to combine multiple validation rules in a single go.
In fact, I would say that we've thoroughly used cascading in our earlier examples. Recall that pipe operator that was used to combine multiple rules—and yes, the so-called cascading validation rules.
Grab the code of the cascade
method.
public function cascade() { // basic required field with cascaded rules $this->form_validation->set_rules('text_field', 'Text Field One', 'required|alpha|min_length[8]|max_length[20]'); if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } }
As shown in the example above, we've applied four validation rules separated by the |
operator to the text_field
text box. So it has to go through each and every rule for the form validation to succeed in this case!
Give it a try and see how it works!
Next, there's a prepping that allows you to apply certain operations on the data that's being submitted. More often than not, you want to remove leading and trailing spaces in the user submitted data. Probably the first thing that comes to your mind in this case is to use the trim function, and the good news is that you can use it!
That's exactly what our prep
method does.
public function prep() { // basic required field with trim prepping applied $this->form_validation->set_rules('min_text_field', 'Text Field Two', 'trim|required|min_length[8]'); if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } }
As you can see, we've used the word trim
in addition to validation rules. So the data is trimmed first, and then it'll go through the other validation rules. In fact, you could use any PHP function that takes a single argument as per the CodeIgniter documentation.
Try running our example by adding few trailing spaces, and see how it goes.
Customizing Error Messages
If you've had a chance to run the above examples, you may have noticed that the error messages displayed to the user are pretty systematic and machine generated. Maybe you want to be more creative and change them in certain cases.
Let's see how you could change the error message for any validation rule. Pull in the code of the custom_message
method.
public function custom_message() { // field with custom error message $this->form_validation->set_rules('alphabets_text_field', 'Text Field Five', 'required|alpha', array('required'=>'Please enter Text Field Five!','alpha'=>'Only alphabets please!')); if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } }
Please note the fourth argument supplied to the set_rules
method. It contains an array of custom validation messages for each validation rule, and the key of each array item is the validation rule itself.
array( 'required'=>'Please enter Text Field Five!', 'alpha'=>'Only alphabets please!' )
Give it a try, and you should see our custom error messages! Pretty cool, huh?
Custom Validation Callbacks
Although the built-in validation library provides a handful of validation rules already, there's always a need to create a custom one in your day-to-day development work. That's exactly what we'll discuss in this section.
To demonstrate that, we'll create a custom validation callback, and later on we'll see how to use it along with the set_rules
method.
To start with, let's have a quick look at the custom_rule
method.
public function custom_rule() { // field with custom validation callback passed $this->form_validation->set_rules('text_field', 'Text Field Five', 'callback_custom_validation'); if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } }
It's no different than the usual set_rules
method call except that we've provided the custom validation callback custom_validation
instead of any core validation rule. The important thing to note here is that you need to prefix the custom validation callback with callback_
when you pass it as an argument.
Next, let's implement the custom validation callback.
public function custom_validation($field_value) { if ($field_value == '' || $field_value == 'demo') { $this->form_validation->set_message('custom_validation', "Come on, don't act like spammer!"); return FALSE; } else { return TRUE; } }
When your custom validation callback is called, the value entered by the user will be passed as the first argument. So the $field_value
contains a value that's entered by a user, against which you can implement your custom validation logic.
In the example above, you should see the error message if you enter either a blank value or demo
in the text field Text Field Five
. It's important to note that when you set the error message using the set_message
method, the first argument is the name of the custom validation callback method itself.
And that's the story of custom validation callbacks.
Last but not least, it's the validation configuration that deserves some attention as we move towards the conclusion of this article.
Validation Configuration
As a CodeIgniter developer, you should already be familiar with the config
directory, which allows you to configure different aspects of your CodeIgniter application.
For example, database.php
allows you to define the database-related settings, while autoload.php
allows you to define the components that should be auto-loaded during the bootstrapping of an application.
In the same way, you could create the form_validation.php
file under the config
directory and use that file to define application-level validation rules that can be used globally. If that sounds alien to you, there's no better way to understand it than actually looking at a practical example.
Create the file application/config/form_validation.php
with the following contents.
<?php $config = array( array( 'field' => 'text_field', 'label' => 'Text Field One', 'rules' => 'required' ), array( 'field' => 'min_text_field', 'label' => 'Text Field Two', 'rules' => 'required|min_length[8]' ), array( 'field' => 'max_text_field', 'label' => 'Text Field Three', 'rules' => 'required|max_length[20]' ) );
Now, let's quickly look at what our configuration
method looks like.
public function configuration() { // if you pass group id, only elements in that group will be validated // $this->form_validation->run('group_one') if ($this->form_validation->run() == FALSE) { $this->load->view('validate_form'); } else { // load success template... echo "It's all Good!"; } }
Try running http://your-codeigniter-site/validation/configuration and submit an empty form. You'll see error messages for three form fields! But wait, where do they come from, since we haven't set up any validation rules in our configuration method in the first place?
Users with sharp eyes would have noticed that it's automatically picked up from the validation configuration file defined at application/config/form_validation.php
. Isn't that amazing? It allows you to centralize the rules in one place and reduces the code duplication in action methods.
In fact, you could group the rules and apply validation to the fields of only a certain group. Let's see how to do that.
Replace the code in application/config/form_validation.php
with the following.
<?php $config = array( 'group_one' => array( array( 'field' => 'text_field', 'label' => 'Text Field One', 'rules' => 'required' ) ), 'group_two' => array( array( 'field' => 'min_text_field', 'label' => 'Text Field Two', 'rules' => 'required|min_length[8]' ), array( 'field' => 'max_text_field', 'label' => 'Text Field Three', 'rules' => 'required|max_length[20]' ) ) );
In your configuration
method, find the following line:
if ($this->form_validation->run() == FALSE)
And replace it with:
if ($this->form_validation->run('group_one') == FALSE)
Now, try to submit an empty form, and you'll see an error for only Text Field One
. That's because we've passed group_one
as a group id, so only the elements in that group will be validated.
Finally, let's have a look at the type of configuration that allows you to define rules based on the URL.
Replace the code in application/config/form_validation.php
with the following code.
$config = array( 'validation/configuration' => array( array( 'field' => 'max_text_field', 'label' => 'Text Field Three', 'rules' => 'required|max_length[20]' ) ) );
In this type of configuration, you need to use a combination of the controller name and the method name separated by the /
character. In this way, you could define rules for several action methods at once.
Now, you should see the error message for Text Field Three
should you try to submit an empty form at http://your-codeigniter-site/validation/configuration.
And that ends the story of validation configuration and this article as well!
Conclusion
In this article, we thoroughly discussed form validation in CodeIgniter.
We started our journey with the basic validation rules, and then we moved to more advanced topics like cascading, prepping, and configuration validation.
I hope you've enjoyed this article, and you can share your valuable views using the feed below!
No comments:
Post a Comment