Form validation is an important part of any application. Take a look at your favorite web application, notice that there are many forms in these web apps, and it is important that they be secure. It is also important that you have rules that should be adhered to; this also helps to keep a layer of security.
In this article by Adam Griffiths, author of CodeIgniter 1.7 Professional Development, you will:
By using form validation and creating rules, you will disallow most, if not all, of these practices from occurring. By having set validation rules you can limit the types of data being allowed in your forms. Best of all, the Form Validation Library makes it easy to re-populate your form fields and to show individual errors for each field, making the overall end user experience better; which can mean a lot in an environment with many forms.
Even if you are building a contact form, it is a good idea to validate your forms to stop people abusing your form.
The rule matches[] will return TRUE if the field matches the field name passed to it.
The min_length[], max_length[], and exact_length[] rules will take an integer as a parameter and check if the minimum length, maximum length respectively, or exact length matches the rule.
The rules with no parameters are pretty much self-explanatory. You are able to use more than one rule, simply separate rules with a vertical bar '|' and they will cascade.
The function prep_for_form will convert special characters so that HTML data can be shown in a form without breaking it.
The function prep_url will simply add http:// to a URL, if it is missing.
The function strip_image_tags will remove image tags, leaving the RAW image URL.
The function encode_php_tags will convert PHP tags into entities.
Say, for example, you want to add the user's e-mail address to the database if they haven't sent you an e-mail before. We can do this with a callback.
Firstly though, let's create the database table. There will be three fields: an ID, the user's name, and the user's e-mail address.
Firstly, we will want to see if the e-mail already exists in the database; if so we won't do anything. If the e-mail isn't in the database, we'll add it along with the persons name.
To do this, we will use a helper function provided by the database library called num_rows.
In this article by Adam Griffiths, author of CodeIgniter 1.7 Professional Development, you will:
- Learn how the form validation process works
- Build a contact form
- Apply validation rules to the form's input fields
- Use callbacks to create your own rules
(Read more interesting articles on CodeIgniter 1.7 Professional Development here.)
Why should I validate my forms?
The answer to this question is simple: security. If you simply left your forms bare, with no validation, and then stored this information directly in a database, you are liable to attack. People can simply place in some SQL code and can see a dump of a part or all of your database.By using form validation and creating rules, you will disallow most, if not all, of these practices from occurring. By having set validation rules you can limit the types of data being allowed in your forms. Best of all, the Form Validation Library makes it easy to re-populate your form fields and to show individual errors for each field, making the overall end user experience better; which can mean a lot in an environment with many forms.
Even if you are building a contact form, it is a good idea to validate your forms to stop people abusing your form.
Using the Form Validation Library
In this article, we'll go over a Contact Form and how to use the Form Validation Library methods for validation.The form validation process
The Form Validation processes are different for the developers and for users. Read on to see how the user interacts with the forms, as well as how the developer will create the forms.The user's process
A form is displayed to the user, who then fills it in and submits it. The Form Validation Library then checks the form against any rules that the developer has set. If an error occurs the library returns these errors and they are shown against the form with the fields re-populated. This process proceeds until a valid form is submitted.The development process
You create a form, along with a dynamic value from a form helper function—this will re-populate the data if needed. You will also display individual or global errors in the form view file. You set validation rules, which must be adhered to. Then you check to see if the validation process has been run, and if it has not, you load the form view file.Contact form
We validate the form data using the Form Validation Library to complete tasks such as checking for empty fields, validating the e-mail, and then send the e-mail off. All of the code shown should be in the index() function of your email controller.Loading the assets
We need to load two libraries for our contact form: the Form Validation Library and the Email class. We can do this in one line, by passing an array to the load->library function.We also need to load two helpers: the email helper and the form helper. We will do this in the same way as we loaded the two libraries in the previous line of code.$this->load->library(array('email', 'form_validation'));
$this->load->helper(array('email', 'form'));
Setting the rules
The next step in using the Form Validation Library is to set the rules for the form. These rules are set and must be adhered to. The way we set rules is by using the set_rules() function of the Form Validation Library. We use the function as follows:As you can see, the function accepts three parameters. The first is the name of the form field that you wish to set the rule for. The second parameter is the name that you wish to be assigned to this, for humans to read. The final parameter is where you pass any validation rules.$this->form_validation-> set_rules('field_name', 'human_name', 'rules');
List of validation rules
The following rules are readily available for use:- required
- matches[field_name]
- min_length[x]
- max_length[x]
- exact_length[x]
- alpha
- alpha_numeric
- alpha_dash
- numeric
- integer
- is_natural
- is_natural_no_zero
- valid_email
- valid_emails
- valid_ip
- valid_base64
The rule matches[] will return TRUE if the field matches the field name passed to it.
The min_length[], max_length[], and exact_length[] rules will take an integer as a parameter and check if the minimum length, maximum length respectively, or exact length matches the rule.
The rules with no parameters are pretty much self-explanatory. You are able to use more than one rule, simply separate rules with a vertical bar '|' and they will cascade.
These rules can also be called as discrete functions. You may also use any native PHP function that accepts one parameter as a rule.
$this->form_validation->required($string); $this->form_validation->is_array($string); // native PHP // function as a rule
Prepping data
We can also use various prepping functions to prep the data before we apply rules to it. Here's a list of the prepping rules that we can perform:- xss_clean
- prep_for_form
- prep_url
- strip_image_tags
- encode_php_tags
The function prep_for_form will convert special characters so that HTML data can be shown in a form without breaking it.
The function prep_url will simply add http:// to a URL, if it is missing.
The function strip_image_tags will remove image tags, leaving the RAW image URL.
The function encode_php_tags will convert PHP tags into entities.
You may also use any native PHP function that accepts one parameter as a rule.
The rules
Now that we know how to set rules and what the rules we can use are, we can go ahead and set the rules necessary for our form. All fields should be required, and the e-mail field should be validated to ensure that the e-mail address is correctly formatted. We also want to run all of the data through the XSS filter.$this->form_validation-> set_rules('name', 'Name', 'required|xss_clean'); $this->form_validation-> set_rules('email', 'Email Address', 'required|valid_email|xss_clean'); $this->form_validation-> set_rules('subject', 'Subject', 'required|xss_clean'); $this->form_validation-> set_rules('message', 'Message', 'required|xss_clean');
Check the validation process
Instead of checking one of the form field's POST value to check if the form has been submitted, we simply check to see if the Form Validation Library has run. We do this by using the following code:It's fairly simple: if the Form Validation Library hasn't processed a form, we display the form to the user; if the library has processed a form and there are no errors, we'll send the e-mail off.if($this->form_validation->run() === FALSE) { // load the contact form } else // send the email }
Sending the email
As you'll notice, everything is the same as how we got the field data earlier.$name = $this->input->post('name'); $email = $this->input->post('email'); $subject = $this->input->post('subject'); $message = $this->input->post('message'); $this->email->from($email, $name); $this->email->to('youremail@yourdomain.ext'); $this->email->subject($subject); $this->email->message($message); $this->email->send();
Final controller code
Here is the entirety of our controller code:<?php class Email extends Controller { function Email() { parent::Controller(); } // function Email() function index() { $this->load->library(array('email', 'form_validation')); $this->load->helper(array('email', 'form')); $this->form_validation-> set_rules('name', 'Name', 'required|xss_clean'); $this->form_validation-> set_rules('email', 'Email Address', 'required|valid_email|xss_clean'); $this->form_validation-> set_rules('subject', 'Subject', 'required|xss_clean'); $this->form_validation-> set_rules('message', 'Message', 'required|xss_clean'); if($this->form_validation->run() == FALSE) { $this->load->view('email'); // load the contact form } else { $name = $this->input->post('name'); $email = $this->input->post('email'); $subject = $this->input->post('subject'); $message = $this->input->post('message'); $this->email->from($email, $name); $this->email->to('youremail@yourdomain.ext'); $this->email->subject($subject); $this->email->message($message); $this->email->send(); } } // function index() } // class Email extends Controller ?>
(Read more interesting articles on CodeIgniter 1.7 Professional Development here.)
Changes to the form view
There are a couple of changes that we need to make to the form view in order to get the data to re-populate, and to show any errors next to the form field.Re-populating field values
This is a fairly simple process. If an error has occurred, all we need to do to get the field data to re-populate is to set the value attribute of our input box. We then set the value using a form helper function, set_value(). We pass the name of the form field to the first parameter of this function.value="<?php echo set_value('name'); ?>"
Showing individual errors
To display the errors, we do the same as we did earlier, but this time we use a different function and place it below the input box. The function that we use this time is form_error().<?php echo form_error('name'); ?>
Final form view
Here is the complete code for our view file:The form should appear as follows:<?php echo form_open(); ?> Name<br /> <input type="text" name="name" value="<?php echo set_value('name'); ?>" /> <?php echo form_error('name'); ?><br /> Email<br /> <input type="text" name="email" value="<?php echo set_value('email'); ?>" /> <?php echo form_error('email'); ?><br /> Subject<br /> <input type="text" name="subject" value="<?php echo set_value('subject'); ?>" /> <?php echo form_error('subject'); ?><br /> Message<br /> <textarea rows="17" cols="70" name="message"> <?php echo set_value('message'); ?></textarea> <?php echo form_error('message'); ?><br /> <input type="submit" name="contact" value="Send Email" /> <?php echo form_close(); ?>
Changing the error delimiters
You can change the way that the errors are displayed to have them contained within custom HTML tags. This is useful for when you want to assign a CSS class in order to the errors to display them differently.Changing delimiters globally
To change the error delimiters globally, add the next line of code after loading the Form Validation Library:$this->form_validation-> set_error_delimiters('<div class="error">', '</div>');
Changing delimiters individually
You can change the delimiters on a case-by-case basis. In the form view file change the way you show the errors by including two parameters in the errors function(s).You can also use:<?php echo form_error('field name', '<div class="error">', '</div>'); ?>
<?php echo validation_errors('<div class="error">', '</div>'); ?>
Saving sets of validation rules to a config file
You can save sets of rules to a config file. To start, create a new file called form_validation.php, inside the application/config/ directory. The rules must be contained within a variable $config, as with all other config files. The rules from our contact form would now appear as follows:$config = array( array( 'field' => 'name', 'label' => 'Name', 'rules' => 'required|xss_clean' ), array( 'field' => 'email', 'label' => 'Email Address', 'rules' => 'required|valid_email|xss_clean' ), array( 'field' => 'subject', 'label' => 'Subject', 'rules' => 'required|xss_clean' ), array( 'field' => 'message', 'label' => 'Message', 'rules' => 'required|xss_clean' ) );
Creating sets of rules
If you have more than one form that needs validating, you can create sets of rules. To do this, you need to place the rules into 'sub-arrays'. The rules for our contact form would appear as follows when we place it into a set:This method allows you to have as many sets of rules as you need.$config = array( 'email' => array( array( 'field' => 'name', 'label' => 'Name', 'rules' => 'required|xss_clean' ), array( 'field' => 'email', 'label' => 'Email Address', 'rules' => 'required|valid_email|xss_clean' ), array( 'field' => 'subject', 'label' => 'Subject', 'rules' => 'required|xss_clean' ), array( 'field' => 'message', 'label' => 'Message', 'rules' => 'required|xss_clean' ) ) );
Calling a specific set of rules
You need to specify the rule set that you want to validate the form against, on the run function. Our edited controller would now look like this:if($this->form_validation->run('email') == FALSE) { $this->load->view('email'); // load the contact form } else { // send the email
Associating a rule group with a controller
You can use these groups to automatically associate them with a controller and function. This time, instead of calling the group email, we'll call it email/index—this will associate the rule group with the controller email and the function index.This way, you won't need to explicitly say which rule group you want your form to be validated against.$config = array( 'email/index' => array( array( 'field' => 'name', 'label' => 'Name', 'rules' => 'required|xss_clean' ), array( 'field' => 'email', 'label' => 'Email Address', 'rules' => 'required|valid_email|xss_clean' ), array( 'field' => 'subject', 'label' => 'Subject', 'rules' => 'required|xss_clean' ), array( 'field' => 'message', 'label' => 'Message', 'rules' => 'required|xss_clean' ) ) );
Using callbacks
The Form Validation Library allows you to use callbacks as rules. A callback is simply a function in your Controller code that is used in place, or along with, a rule.Say, for example, you want to add the user's e-mail address to the database if they haven't sent you an e-mail before. We can do this with a callback.
Firstly though, let's create the database table. There will be three fields: an ID, the user's name, and the user's e-mail address.
CREATE TABLE IF NOT EXISTS `user_data` ( `id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , `name` VARCHAR( 255 ) NOT NULL , `email` VARCHAR( 255 ) NOT NULL );
Include the callback in the rules
To add a callback into the rules, simply prefix the name of the function with callback_. Here is the rule for the e-mail field, again, with our callback added:Here you can see that we've added the rule callback_add_user—this will run the e-mail through the function add_user() in our controller.$this->form_validation-> set_rules('email', 'Email Address', 'required|valid_email|callback_add_user|xss_clean');
Creating the callback
To create the callback, first we need to decide how it will work.Firstly, we will want to see if the e-mail already exists in the database; if so we won't do anything. If the e-mail isn't in the database, we'll add it along with the persons name.
Create the function
Creating a function is easy. A note about using callbacks, first. When using a callback, the Form Validation Library will pass the value of the field to the callback, so to get the e-mail into our callback we simply need to create a variable to retrieve it.function add_user($email) { }
Load the database library
We'll need to load the database library. We do this slightly differently than other libraries, because it is larger than the others.$this->load->database();
Performing the database query
To perform a basic SQL query, we use the following function:So our code will look like this:$this->db->query();
$query = $this->db-> query("SELECT * FROM `user_data` WHERE `email` = '$email'");
Adding a condition
We only want to add the user's name and their e-mail address if the email doesn't exist already. To do this, we'll need to check to see if the number of rows returned from the query is zero.To do this, we will use a helper function provided by the database library called num_rows.
if($query->num_rows() === 0) { $name = $this->input->post('name'); $this->db-> query("INSERT INTO `user_data` (name, email) VALUES ('$name', '$email')"); }
In this example we used an explicit comparison (===); we check that the value of the number of rows returned is identical to 0. If we had used == then the result FALSE would run through the comparison as TRUE> and the code in the loop would run when we didn't want it to.
You will also notice from this code that we are using the same function as we did to get the data from the database to insert the e-mail as well. The code inside the if statement will only be run if there is no previous record of the e-mail in the database.Show a success page
To show the user that some progress has been made, let's add in the success page. Find the following line of code:Add the following lines below it:$this->email->send();
Now, create a file inside the system/application/views/ folder called email_success.php and add the following line of code into it.$data['msg'] = "Thank you, your email has now been sent."; $this->load->view('email_success', $data);
All we need to do is echo the variable out. You should, of course, add any layout code if you're using this on a live website, because at the moment, we simply display the message as seen in the next screenshot.<?php echo $msg; ?>
No comments:
Post a Comment