PHP - - By Iain Tench

Form Validation with PHP

In this article you’ll construct and validate a simple form using HTML and PHP. The form is created using HTML and validation and processing of the form’s contents is done with PHP. The goal is to teach you some basic HTML form elements and how their data is accessible to you in your PHP scripts.

The form you’ll create contains a number of inputs: text fields, radio buttons, a multiple-option select list, a checkbox, and a submit button. These inputs will be validated to ensure, for example, that the user has entered their name. Any errors or omissions will be highlighted with a message alongside the relevant field.

The HTML Form

First, let’s look at the form. The purpose of the form is to capture user details (name, address, and email) to obtain feedback (on fruit consumption and favorite fruit) and request a brochure.

Text Fields

The name, address, and email fields are text input elements and can be coded like this:

Name <input type="text" name="name" value="">
Address <input type="text" name="address" value="">
Email <input type="text" name="email" value="">

The HTML input element can have several attributes, the most important of which are the type and name attributes. type="text" defines these instances as a single-line input field to accept text. The name attribute is used to specify a name for this value.

Radio Buttons

<input type="radio" name="howMany" value="zero"> 0
<input type="radio" name="howMany" value="one"> 1
<input type="radio" name="howMany" value="two"> 2
<input type="radio" name="howMany" value="twoplus"> More than 2

Here type="radio" renders the input as a radio button. Notice how each button is assigned the same name. This is because collectively the radio buttons should be treated as a group (the user should select either 0, or 1, or 2, etc.). The value attribute differs for each button to provide the different selections that can be made.

Select List

<select name="favFruit[]" size="4" multiple>
 <option value="apple">Apple</option>
 <option value="banana">Banana</option>
 <option value="plum">Plum</option>
 <option value="pomegranate">Pomegranate</option>
 <option value="strawberry">Strawberry</option>
 <option value="watermelon">Watermelon</option>
</select>

In this case, the name attribute of the select element is given as an array (with square brackets) because multiple choices are allowed (because of the presence of the multiple attribute). Without multiple, only one option would be selectable.

Each option specified within the select has a distinct value. The value attribute for each option element is the value that will be submitted to the server, and the text between the opening and closing option tag is the value the user will see in the menu.

Checkbox

<input type="checkbox" name="brochure" value="Yes">

The input is presented as a checkbox. Its value will be set to “Yes” if the box has been checked.

Submit Button

<input type="submit" name="submit" value="Submit">

Last but not least there is the submit button. Its value is presented as its label, and clicking on it will trigger the form submission.

The Form Element

There are two specific attributes that need to be set in the form tag, action and method:

<form method="POST"
 action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

htmlspecialchars() is used here to convert specific HTML characters to their HTML entity names, e.g. > will be converted to &gt;. This prevents the form from breaking if the user submits HTML markup and also is a means of protecting against XSS (Cross Site Scripting) attacks, which attackers will use to try to exploit vulnerabilities in web applications.

action defines where the form contents are sent when the form is submitted; in this case, the value of $_SERVER["PHP_SELF"].

$_SERVER is an array with entries filled in at PHP run time; the PHP_SELF key contains the filename of the PHP script that is being executed. Using $_SERVER["PHP_SELF"] is preferable to simply hard-coding a location if you want your form to post back to the same script that generated it since you won’t have to update the code if you change the script’s name.

method determines how the form’s contents is submitted. POST means that the form’s content is sent as part of the HTTP request’s body. The values are then retrievable in PHP using the $_POST array.

The alternative to POST is GET which passes the form’s values as part of the URL. Values sent using GET are retrievable in PHP using $_GET. The main difference between the methods POST and GET is visibility. There are numerous articles on the web about choosing between them, but my advise is to stick to POST when using forms unless you have a good reason to pass user data in a viewable URL.

Remember that when working with HTML forms:

  • All of the form controls must be enclosed within the form tags.
  • The alignment of text and form controls can be achieved in many ways. CSS is the preferred option for many, but be prepared to see tables used for alignment in older HTML.
  • Not discussed here, but important for accessibility is the label element.

Form Processing

Now that you’ve defined the form in HTML, let’s identify the two stages the form goes through – when the blank form is loaded, and when the user has completed the form and clicks the submit button. The script needs to be able to differentiate between the two stages so the form behaves properly.

To determine whether the form has been submitted by the user, either check the request method (an example follows in the next section) or check for the presence of a specific form control (usually the submit button).

Whichever method you use, if the form has been submitted, it should be validated. If it has not been submitted, bypass the validation and display a blank form.

Capturing the Form Contents

So far, we have a largely HTML page which defines the form; the only PHP so far is to specify the form’s action value. We need to add code which will pick up the form data and allow us to check it and create error messages if needed.

At the start of the script, before any HTML, you can check whether the form has been submitted using $_SERVER["REQUEST_METHOD"]. If the REQUEST_METHOD is POST, then you know the script has been submitted.

Detecting a form submission is a little bit trickier when you’re using GET, because just requesting the page to view the form will probably happen as a GET request as well. One common work around is provide a name attribute to the submit button, and check whether it is set in the $_GET array with isset(). For example:

<input type="submit" name="submit" value="Submit">
<?php
if (isset($_GET["submit"])) {
    // process the form contents...
}

Validating the Form Contents

When the form is submitted, the following entries will be stored in the $_POST array (or $_GET array depending on the form’s method attribute). The values in the left-hand column are taken from the control’s name attribute, and I’ve also marked whether or not the field is a required field for validation purposes.

If the user does not comply with these rules, an error message will be displayed. Any fields already completed will be left unchanged, allowing the user to simply adjust her input and re-submit the form without having to enter all of the data again. See example below.

Let’s look at the PHP required for validating the form. All of this code would be placed towards the top of the page before the HTML for the form:

<?php
// define variables and initialize with empty values
$nameErr = $addrErr = $emailErr = $howManyErr = $favFruitErr = "";
$name = $address = $email = $howMany = "";
$favFruit = array();

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if (empty($_POST["name"])) {
        $nameErr = "Missing";
    }
    else {
        $name = $_POST["name"];
    }

    if (empty($_POST["address"])) {
        $addrErr = "Missing";
    }
    else {
        $address = $_POST["address"];
    }

    if (empty($_POST["email"]))  {
        $emailErr = "Missing";
    }
    else {
        $email = $_POST["email"];
    }

    if (!isset($_POST["howMany"])) {
        $howManyErr = "You must select 1 option";
    }
    else {
        $howMany = $_POST["howMany"];
    }

    if (empty($_POST["favFruit"])) {
        $favFruitErr = "You must select 1 or more";
    }
    else {
        $favFruit = $_POST["favFruit"];
    }
}
// the HTML code starts here

The code starts by creating and initializing the variables used in the validation process:

  • A variable for each of the text fields and the favourite fruit array
  • Error message variables for each field

The exception is the brochure checkbox which does not need to be validated as it is an optional field.

Next determine whether the form has been submitted by checking how the page was requested. If the form has just been requested, then the if statement will be bypassed. The function empty() checks the text fields for name, address, and email, and the array for favorite fruit. isset() checks whether a radio button is set for the fruit count. If any are empty, a suitable error message is assigned to the error variable.

In the example here I am checking the $_POST array because the form’s method is POST. If method was GET, then I would check the $_GET array for the input values.

Having run these checks, the code would continue with the HTML for the page. PHP needs to be incorporated into the HTML for each element:

  1. To print the value submitted in the text fields so the user does not have to retype it. The value will of course be blank if the form has just been loaded and not submitted.
  2. To print any error messages. Again these will be blank if the form has just been loaded or if there is no error for the field.

Here is the HTML definition of one of the input fields:

<input type="text" name="name" value="">

And here is the same code amended to include the first point specified above:

<input type="text" name="name"
 value="<?php echo htmlspecialchars($name);?>">

And then again to address the second point above:

<input type="text" name="name"
 value="<?php echo htmlspecialchars($name);?>">
<span class="error"><?php echo $nameErr;?></span>

htmlspecialchars() is used here for the same reason it was used earlier with PHP_SELF – to protect against XSS attacks.

The use of the class error provides a hook with which you can style the error message using CSS.

.error {
    color: #FF0000;
}

Extending the Form’s Usability

With a little more effort, you can also remember the choices the user made from the radio buttons and select.

<input type="radio" name="howMany" 
 <?php if (isset($howMany) && $howMany == "zero") echo "checked"; ?>
 value="zero"> 0
<input type="radio" name="howMany"
 <?php if (isset($howMany) && $howMany == "one") echo "checked"; ?>
 value="one"> 1
<input type="radio" name="howMany"
 <?php if (isset($howMany) && $howMany == "two") echo "checked"; ?>
 value="two"> 2
<input type="radio" name="howMany"
 <?php if (isset($howMany) && $howMany == "twoplus") echo "checked"; ?>
 value="twoplus"> More than 2

Code has been added to check whether the variable associated with the radio button has been defined within the validation section. If so, then checked is outputted as part of the element’s HTML.

Now to address the select menu. It is actually a better idea to restructure the code as a loop than to blindly add code to check each option manually. The loop would generate the HTML for the options on the fly, and the check if the option has been selected or not can be incorporated into it.

<select name="favFruit[]" size="4" multiple="">
<?php
$options = array("apple", "banana", "plum", "pomegranate", "strawberry", "watermelon");
foreach ($options as $option) {
    echo '<option value="' . $option . '"';
    if (in_array($option, $favFruit)) {
        echo " selected";
    }
    echo ">" . ucfirst($option) . "</option>";
}
?>
</select>

If you are not yet familiar with PHP loops, you may want to read my earlier article, Learning Loops.

Note that the difference here is the use of the attribute selected; radio buttons use checked and select options use selected. It’s just one of those minor inconsistencies we have to live with.

One topic which I have not addressed and is outside the scope of this article is what you would do with the data after validation is successful. There are a number of possibilities, including saving it in a database or emailing the data to yourself. Whichever you choose, you need to be sure:

  • The form has been submitted by the user
  • The data entered by the user is error-free

Summary

Validation is essential, particularly if you are going to save the data in a database – remember the old saying, GIGO (Garbage In, Garbage Out), and you won’t go far wrong. In this article you have learned how to create a simple HTML form and validate it with PHP. Along the way a number of techniques have been used to re-display user input and display error messages. For further information on $_SERVER, $_POST, and $_GET, read the article Introducing Superglobals and of course the PHP documentation.

And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like Jump Start PHP.

Comments on this article are closed. Have a question about PHP? Why not ask it on our forums?

Image via Valentyn Volkov / Shuttestock

Sponsors