Main Page Content
User Friendly Forms In Php
Have you ever been filling in a form online and you forget to fill in a required field, or it requires a US zip code, or certain characters are banned etc etc and when you submit the form you get an undescriptive error, then when you hit "back" in your browser, all the information you entered into the form has disappeared and you have to fill it all in again? Annoying isn't it?
In this tutorial I'll show you a way to make your forms more friendly with PHP, so users don't have to keep filling forms in if they make a mistake -- make your forms more friendly.
How
By putting in just a little extra effort we can make our forms display the errors and show the form again, with the fields the user already filled in completed. Here's what we do:
- Create a function to output our form that pre-fills the inputs with values, if they've already been entered.
- Perform our data checks and ensure everything is in order.
- If there's a mistake, append the description to a variable --
$error_str
. - If
$error_str
is not empty, halt the script execution, show the errors in$error_str
and recall the form function. - Otherwise continue processing the script as normal.
Putting this into code
The first step is to create our form function. Let's imagine we want a user to submit their first name, second name, age, location and gender. We need to create a function that outputs this form and holds any values the user has already entered.
<?php// function to output form and hold previously entered values.function user_form() {
// if vars aren't set, set them as empty. // (prevents "notice" errors showing for those who have them enabled) if (!isset($_POST['first_name'])) $_POST['first_name'] = ''; if (!isset($_POST['second_name'])) $_POST['second_name'] = ''; if (!isset($_POST['age'])) $_POST['age'] = ''; if (!isset($_POST['location'])) $_POST['location'] = ''; if (!isset($_POST['gender'])) $_POST['gender'] = ''; // now to output the form HTML. echo '<p>All fields are required.</p>'; echo '<form action="'.htmlspecialchars($_SERVER['PHP_SELF']).'" method="post">'; echo '<table border="0" cellspacing="4" cellpadding="0">'; echo '<tr><td>First name:</td><td><input type="text" name="first_name" value="'.htmlspecialchars($_POST['first_name']).'"></td></tr>'; echo '<tr><td>Second name:</td><td><input type="text" name="second_name" value="'.htmlspecialchars($_POST['second_name']).'"></td></tr>'; echo '<tr><td>Age:</td><td><input type="text" name="age" value="'.htmlspecialchars($_POST['age']).'"></td></tr>'; echo '<tr><td>Location:</td><td><input type="text" name="location" value="'.htmlspecialchars($_POST['location']).'"></td></tr>'; // let's make the gender input a select box // you can see how we pre-select an option echo '<tr><td>Gender:</td><td><select name="gender">'; echo '<option value="male"'; if (strtolower($_POST['gender']) == 'male' empty($_POST['gender'])) echo ' selected="selected"'; echo '>Male</option>'; echo '<option value="female"'; if (strtolower($_POST['gender']) == 'female') echo ' selected="selected"'; echo '>Female</option>'; echo '</select></td></tr>'; echo '<tr><td colspan="2"><input type="submit" value="Submit" name="submit"></td></tr>'; echo '</table>'; echo '</form>';}?>
Okay, there we have it. This function will print out the form, and pre-fill the text inputs with their $_POST indexes. We also have a <select> box. If $_POST['gender']
is empty or "male", the "Male" select option will be selected. If it is "female" the "Female" option will be selected.
This means that if a user has submitted the form and we have to show it again, because of errors, the values they entered will be there again, they won't have to fill every one in again.
Note: Remember, if you are pre-filling a form input with a variable value, always ensure that you use htmlspecialchars(). If the variable contains a quote, your form won't like it. If the variable contains HTML, they will be properly converted to HTML entities. If the variable contains HTML entities, and we did not use htmlspecialchars(), they would show as the character they represent when the form is called, not the actual entitiy. For example, if a user submitted < in the form and the function was recalled, it would show as < on the next page. Using htmlspecialchars() will ensure the entity remains as <, preserving the data properly.
Data Checking
Whenever you allow a user to submit data through a form, always remember to be paranoid. Do not assume the form they submitted to your script is the form you have written, it is very easy for a user to make a copy of the form and send in data they shouldn't be able to. For instance we have only "male" and "female" options available for the "gender" select input. A user could easily copy the form and edit it, add another option and submit to your script, we must ensure we check the data properly.
<?php// assuming we saved the above function in "functions.php", let's make sure it's available
require_once 'functions.php';// has the form been submitted?
if (isset($_POST['submit'])) { // the form has been submitted // perform data checks. $error_str = ''; // initialise $error_str as empty if (empty($_POST['first_name'])) $error_str .= '<li>You did not enter your first name.</li>'; if (empty($_POST['second_name'])) $error_str .= '<li>You did not enter your second name.</li>'; if (empty($_POST['age'])) $error_str .= '<li>You did not enter your age.</li>'; if (empty($_POST['location'])) $error_str .= '<li>You did not enter your location.</li>'; if (empty($_POST['gender'])) $error_str .= '<li>You did not enter your second name.</li>'; // more checks if (strlen($_POST['first_name']) < 2) $error_str .= '<li>Your first name must be longer than one letter.</li>'; if (strlen($_POST['second_name']) < 2) $error_str .= '<li>Your second name must be longer than one letter.</li>'; if (!is_numeric($_POST['age'])) $error_str .= '<li>Your age must be a numeric value.</li>'; if (strtolower($_POST['gender']) != 'male' && strtolower($_POST['gender']) != 'female') $error_str .= '<li>Your gender can only be male or female.</li>'; // we could do more data checks, but you get the idea. // we could also strip any HTML from the variables, convert it to entities, have a maximum character limit on the values, etc etc, but this is just an example. // now, have any of these errors happened? We can find out by checking if $error_str is empty if (!empty($error_str)) { // errors have occured, halt execution and show form again. echo '<p>There were errors in the information you entered, they are listed below:</p>'; echo '<ul>'.$error_str.'</ul>'; // show form again user_form(); exit; // die } // if we get here, all data checks were okay, process information as you wish.} else { // the form has not been submitted, let's show it user_form();}?>
There we have it. Using a function to display the form makes it easy for us to make our forms more friendly. I know I have given up and left sites because the forms kept wiping the data I'd already entered, if you want to keep users happy put in a little extra effort to ensure they do as little work as possible.