Richland College Multimedia Learning Center

Digital Media Programming with PHP and MySQL

Digital Media Programming with PHP and MySQL

PHP Form Validation

Introduction

You need to validate the information that your Web page users enter into your HTML forms. You are inviting disaster if you don't, especially if you use the form's information to add information to your database. You don't want junk in your database!

Form validation can be done in both the browser (called "Client-Side Validation"), usually with JavaScript; and at the Web server (called "Server-Side Validation"), which you can use PHP for quite easily.

And in fact, in the real world a combination of JavaScript and PHP for form validation is a good idea. JavaScript is quick, does not require another page load from the server, and is fairly simple. But what if the user has turned off JavaScript, or their browser doesn't run your JavaScript code quite like you intended? PHP form validation can't be bypassed, so it will always protect your data.

This handout will not cover JavaScript form validation. If you want to learn how to use JavaScript for form validation, there are many good online tutorials, and you can also take my JavaScript class here at Richland in the fall semester!


Simple Form Validation

Before we talk about the Validator Class in most of the rest of this handout, I also want to give you an idea of how simply form validation can be done with PHP, if you have a very simple form and you don't need a lot of fancy validation.

For this simple validation example, we will be using this form.

Here is the form input page, simpleForm.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
  <title>Simple Form Validation</title>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <style type="text/css">
    body { font-family: Arial, sans-serif; }
  </style>
</head>

<body>
  <h3>Fill in this form and click the "Send Your Information" button:</h3>
  <form method="post" action="simpleFormValidation.php">
    Your name:
    <input type="text" name="YourName" />
    <br /><br />
    Your age:
    <input type="text" name="YourAge" />
    <br /><br />
    <input type="submit" value="Send Your Information" />
  </form>
</body>
</html>
  

And now here is the form's action page, simpleFormValidation.php:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
  <title>Simple Form Validation</title>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <style type="text/css">
    body { font-family: Arial, sans-serif; }
  </style>
</head>

<body>
  <h3>Your Form Validation Results:</h3>
  <p>
  <?php
    $yourName = $_POST["YourName"];
    $yourAge = $_POST["YourAge"];
    if ($yourName == "" || $yourAge == "")
    {
      print "Please go back and fill in your:<br />";
      if ($yourName == "")
      {
        print "<br />Name";
      }
      if ($yourAge == "")
      {
        print "<br />Age";
      }
    }
    else
    {
      print "Your Age: " . $yourAge . "<br />";
      print "Your Name: " . $yourName;
      print "<h4>Thank you!</h4>";
    }
  ?>
  </p>
</body>
</html>
  

Please note these points about the above code pages:


A Validator Class

Here is the test form that we will be discussing in the rest of this handout.

The PHP form validation that is described in this handout uses a PHP class (object) to do the work of validation. This use of a class/object is an advantage because the class can be extended if needed in your form, without changing the class definition itself. In other words, you can build your own class by inheriting most of the code from the original class file, and adding or changing only what you need for your specific form. The class definition given in this handout covers the most common types of form validation that are needed.

The class is called FormValidator.

The FormValidator class has many methods that do the work of validating the data. Some (not all) of these methods are:

The FormValidator class uses an associative array to store any error messages that will be presented to the user if any of their data are incorrect.

Here is the very beginning of the FormValidator class code:

    class FormValidator
    {
      ... stuff goes here ...
    }
  

Properties

Now let's look at the properties that are defined in the FormValidator class:

    class FormValidator
    {
      //
      // private variables
      // 
      
      var $_errorList;
    
      ... more stuff goes here ...
    }
  

Please note the underscore (_) that is in the variable (property) name. In this code, an underscore in a variable name is used to indicate that the variable is a private (local) variable.


_getValue() Method

As we look at the validation methods in just a few minutes, you will see that each validation method will be passed the name of the form variable to be tested, as a string. We need a method which will take this string, and use it to obtain the value of the corresponding form variable. Here is that method:

    class FormValidator
    {
      // snip
    
      //
      // methods (private)
      // 
      
      // function to get the value of a variable (field)
      function _getValue($field)
      {
        if (isset($_POST["{$field}"]))
        {
          return $_POST["{$field}"];
        }
        else
        {
          return "";
        }
      }
    
      // snip
    }
  

The _getValue() method will be passed a string representing a particular form variable - for example, "a" - and it will return the value of the corresponding form variable - for example, $_POST["a"]. Note how this code uses PHP's powerful variable interpolation features to return the form value.


isEmpty()

The isEmpty() public method is called with two arguments:

  1. the name of the form variable to be tested, and
  2. the error message to be displayed if it is found to be empty.

This method internally calls the _getValue() method (see the previous section) to obtain the value of the named form variable; it then trim()s this value and checks to see if it is empty.

    class FormValidator
    {
      // snip
    
      //
      // methods (public)
      //
    
      // check whether input is empty
      function isEmpty($field, $msg)
      {
        $value = $this->_getValue($field);
        if (!is_array($value) && trim($value) == "")
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return true;
        }
        else
        {
          return false;
        }
      }
    
      // snip
    }

Please note these further points about the above code:


isString()

This method simply uses PHP's built-in variable functions to determine whether the data passed to it is character data.

    class FormValidator
    {
      // snip
    
      // check whether input is a string
      function isString($field, $msg)
      {
        $value = $this->_getValue($field);
        if(!is_string($value))
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
        else
        {
          return true;
        }
      }
    }
  

isNumber()

This method simply uses PHP's built-in variable functions to determine whether the data passed to it is numeric data.

Also see the next two sections for isInteger() and isFloat().

    class FormValidator
    {
      // snip
    
      // check whether input is a number
      function isNumber($field, $msg)
      {
        $value = $this->_getValue($field);
        if(!is_numeric($value))
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
        else
        {
          return true;
        }
      }
    }
  

isInteger()

This useful corollary of the isNumber() method provides for more precise data validation capabilities when dealing with numeric data. Also see the next section for isFloat().

    class FormValidator
    {
      // snip
      
      // check whether input is an integer
      function isInteger($field, $msg)
      {
        $value = $this->_getValue($field);
        if(is_numeric($value))
        {
          if(floatval($value) != intval(floatval($value)))
          {
            $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
            return false;
          }
          else
          {
            return true;
          }
        }
        else
        {
           $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
            return false;
        }
      }
    }
  

Please note these points about the above code:


isFloat()

This useful corollary of the isNumber() method provides for more precise data validation capabilities when dealing with numeric data. Also see the previous section for isInteger().

    class FormValidator
    {
      // snip
    
      // check whether input is a float
      function isFloat($field, $msg)
      {
        $value = $this->_getValue($field);
        if(is_numeric($value))
        {
          $castValue = (float)$value;
          if(!is_float($castValue))
          {
            $this->_errorList[] = array("field" => $field,
              "value" => $value, "msg" => $msg);
            return false;
          }
          else
          {
            return true;
          }
        }
        else
        {
          $this->_errorList[] = array("field" => $field,
            "value" => $value, "msg" => $msg);
          return false;
        }
      }
    }
  

Please note these points about the above code:


isWithinRange()

Another very useful method when building forms which ask for such things as the user's age, is the isWithinRange() method. It provides an easy way to check whether the input is within a certain numeric range.

    class FormValidator
    {
      // snip
    
      // check whether input is within a valid numeric range
      function isWithinRange($field, $msg, $min, $max)
      {
        $value = $this->_getValue($field);
        if(!is_numeric($value) || $value < $min || $value >
    $max)
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
        else
        {
          return true;
        }
      }
    }
  

isAlpha()

It's also possible to create more complex validation routines using PHP's built-in support for regular expressions. This next method, isAlpha(), uses a regular expression to test whether all the characters in the input string are alphabetic.

    class FormValidator
    {
      // snip
    
      // check whether input is alphabetic
      function isAlpha($field, $msg)
      {
        $value = $this->_getValue($field);
        $pattern = "/^[a-zA-Z]+$/";
        if(preg_match($pattern, $value))
        {
          return true;
        }
        else
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
      }
    
    }
  

isEmailAddress()

This ability to use regular expressions to perform data validation comes in particularly handy when checking user-supplied email addresses for validity - as the very cool (and very useful) class method isEmailAddress() demonstrates:

    class FormValidator
    {
      // snip
    
      // check whether input is a valid email address
      function isEmailAddress($field, $msg)
      {
        $value = $this->_getValue($field);
        $pattern =
    "/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+/";
        if(preg_match($pattern, $value))
        {
          return true;
        }
        else
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
      }
    
    }
  

isError()

Now we need some methods to access the error list.

The first of these is a simple little method named isError(), which lets you know whether or not any errors have occurred yet. Internally, all this method does is check the size of the $_errorList array; if the size of the array is greater than 0, it means that one or more errors have occurred while validating the form data:

    class FormValidator
    {
      // snip
    
      // check whether any errors have occurred in validation
      // returns Boolean
      function isError()
      {
        if (sizeof($this->_errorList) > 0)
        {
          return true;
        }
        else
        {
          return false;
        }
      }
    }
  

getErrorList()

Of course, all isError() does is tell you whether or not an error occurred. To view the list of errors, you need the getErrorList() method, which returns the current $_errorList array:

    class FormValidator
    {
      // snip
    
      // return the current list of errors
      function getErrorList()
      {
        return $this->_errorList;
      }
    
    }
  

resetErrorList()

We will occasionally need to reset the error list to have no errors in it. For this need we have the method resetErrorList(), which clears the $_errorList array of all data.

    class FormValidator
    {
      // snip
    
      // reset the error list
      function resetErrorList()
      {
        $this->_errorList = array();
      }
    }
  

It's a good idea to run this resetErrorList() method whenever the class is first instantiated, which is why a call to it is in the class constructor. See the next section.


getFormattedErrorList()

You can use the getFormattedErrorList() method to get a formatted list of the errors.

Please note that this method first calls the class's getErrorList() method.

    class FormValidator
    {
      // snip
    
      // return a FORMATTED list of errors
      function getFormattedErrorList()
      {
        $errors = $this->getErrorList();
        $formattedErrorList = "<div id='fv_error_div'>\n";
        $formattedErrorList .= "<p><b>The form was not submitted because one or
                               more error(s) occurred.</b></p> <p>Please go back and resubmit
                               the form after making the following changes:</p>\n";
        $formattedErrorList .= "<ul>\n";
        foreach ($errors as $e)
        {
          $formattedErrorList .= "<li>" . $e['msg'] . "</li>\n";
        }   
        $formattedErrorList .= "</ul>\n";
        $formattedErrorList .= "</div>\n";
        
        return $formattedErrorList;
      }
    
    }
  

__construct()

Here is the class's constructor function:

    class FormValidator
    {
      // snip
    
      // constructor
      // reset error list
      function __construct()
      {
        $this->resetErrorList();
      }
    }
  

The Complete Class File

Following is the complete class definition file, FormValidatorClass.php. You can highlight this code, copy it, and paste it into your HTML/text editor. Save it as FormValidatorClass.php.

<?php
    class FormValidator
    {
      //
      // private variables
      // 
      
      var $_errorList;
      
    
      // constructor
      // reset error list
      function __construct()
      {
        $this->resetErrorList();
      }

      
      //
      // methods (private)
      // 
      
      // function to get the value of a variable (field)
      function _getValue($field)
      {
        if (isset($_POST["{$field}"]))
        {
          return $_POST["{$field}"];
        }
        else
        {
          return "";
        }
      }
      
      
      //
      // methods (public)
      //
    
      // check whether input is empty
      function isEmpty($field, $msg)
      {
        $value = $this->_getValue($field);
        if (!is_array($value) && trim($value) == "")
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return true;
        }
        else
        {
          return false;
        }
      }
      
      // check whether input is a string
      function isString($field, $msg)
      {
        $value = $this->_getValue($field);
        if(!is_string($value))
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
        else
        {
          return true;
        }
      }

       // check whether input is a number
      function isNumber($field, $msg)
      {
        $value = $this->_getValue($field);
        if(!is_numeric($value))
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
        else
        {
          return true;
        }
      }
      
      // check whether input is an integer
      function isInteger($field, $msg)
      {
        $value = $this->_getValue($field);
        if(is_numeric($value))
        {
          if(floatval($value) != intval(floatval($value)))
          {
            $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
            return false;
          }
          else
          {
            return true;
          }
        }
        else
        {
           $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
            return false;
        }
      }
    
      // check whether input is a float
      function isFloat($field, $msg)
      {
        $value = $this->_getValue($field);
        if(is_numeric($value))
        {
          $castValue = (float)$value;
          if(!is_float($castValue))
          {
            $this->_errorList[] = array("field" => $field,
              "value" => $value, "msg" => $msg);
            return false;
          }
          else
          {
            return true;
          }
        }
        else
        {
          $this->_errorList[] = array("field" => $field,
            "value" => $value, "msg" => $msg);
          return false;
        }
      }
      
      // check whether input is within a valid numeric range
      function isWithinRange($field, $msg, $min, $max)
      {
        $value = $this->_getValue($field);
        if(!is_numeric($value) || $value < $min || $value >
    $max)
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
        else
        {
          return true;
        }
      }
    
      // check whether input is alphabetic
      function isAlpha($field, $msg)
      {
        $value = $this->_getValue($field);
        $pattern = "/^[a-zA-Z]+$/";
        if(preg_match($pattern, $value))
        {
          return true;
        }
        else
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
      }
    
      // check whether input is a valid email address
      function isEmailAddress($field, $msg)
      {
        $value = $this->_getValue($field);
        $pattern =
    "/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+/";
        if(preg_match($pattern, $value))
        {
          return true;
        }
        else
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
      }
    
      // check whether any errors have occurred in validation
      // returns Boolean
      function isError()
      {
        if (sizeof($this->_errorList) > 0)
        {
          return true;
        }
        else
        {
          return false;
        }
      }
    
      // return the current list of errors
      function getErrorList()
      {
        return $this->_errorList;
      }
    
      // reset the error list
      function resetErrorList()
      {
        $this->_errorList = array();
      }

      // return a FORMATTED list of errors
      function getFormattedErrorList()
      {
        $errors = $this->getErrorList();
        $formattedErrorList = "<div id='fv_error_div'>\n";
        $formattedErrorList .= "<p><b>The form was not submitted because one or
                               more error(s) occurred.</b></p> <p>Please go back and resubmit
                               the form after making the following changes:</p>\n";
        $formattedErrorList .= "<ul>\n";
        foreach ($errors as $e)
        {
          $formattedErrorList .= "<li>" . $e['msg'] . "</li>\n";
        }   
        $formattedErrorList .= "</ul>\n";
        $formattedErrorList .= "</div>\n";
        
        return $formattedErrorList;
      }
    
    }  // end of class
?>
  

The Form

Here is a simple form which will show how to use the FormValidator class. This is file formValidatorTestForm.php:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
  <title>Test the FormValidator Class</title>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <style type="text/css">
  	.formLabel { vertical-align: top; text-align: right; padding-right: 1em; }
  	td, th {padding-top: 1em; }
  	.buttonStyle { text-align: center; }
  </style>
</head>

<body>
  <div style='width: 700px; border: 1px solid gray; border-radius: 2em; margin: 0 auto; padding:1em; font-family: Arial, sans-serif;'>
    <form action="formValidatorAction.php" method="post">
    <table>
    	<tr>
    		<th class="formLabel">Name:</th>
    		<td><input type="text" name="name" size="15" /></td>
    	</tr>	
    	<tr>
    		<th class="formLabel">Telephone Number:</th>
    		<td><input type="text" name="phone" size="20" /></td>
    	</tr>	
    	<tr>
    		<th class="formLabel">Age:</th>
    		<td><input type="text" name="age" size="3" maxlength="3" /></td>
    	</tr>	
    	<tr>
    		<th class="formLabel">Sex:</th>
    		<td><input type="radio" name="sex" value="m" />Male
            <input type="radio" name="sex" value="f" />Female</td>
    	</tr>	
    	<tr>
    		<th class="formLabel">Favorite sandwich type:</th>
    		<td><select name="stype">
            <option value="">-select one-</option>
            <option value="1">Thin crust</option>
            <option value="2">Thick crust</option>
            <option value="3">Toasted</option>
            </select>
        </td>
    	</tr>	
    	<tr>
    		<th class="formLabel">Favorite sandwich filling:</th>
    		<td><input type="checkbox" name="sfill[]" value="BLT" />Bacon, lettuce tomato
            <input type="checkbox" name="sfill[]" value="EC" />Egg and cheese
            <input type="checkbox" name="sfill[]" value="PBJ" />Peanut butter and jelly</td>
    	</tr>	
    	<tr>
    		<th class="formLabel">How much you would pay for the above sandwich:</th>
    		<td><input type="text" name="price" size="10" /></td>
    	</tr>	
    	<tr>
    		<th class="formLabel">Give us your e-mail address, please:</th>
    		<td><input type="text" name="email" size="40" /></td>
    	</tr>	
    	<tr>
    		<td colspan="2" class="buttonStyle"><input type="submit" name="submit" value="Send Your Information" /></td>
    	</tr>	
    </table>
    </form>
  </div>
</body>
</html>
  

The Action Page

When this form is submitted, the PHP script formValidatorAction.php will receive the form variables. The script formValidatorAction.php will first need to verify that the data entered into the form is acceptable, and it uses the FormValidator class to do so. The script then does something with the data (for example, it INSERTs the data into a MySQL database):

Please note that this action page is extending the original class to have a new function, isPhone(). This is one of the powerful features of objects in PHP.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
  <title>Test the FormValidator Class -- Action Page</title>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <style type="text/css">
  	.formLabel { vertical-align: top; text-align: right; padding-right: 1em; }
  	td, th {padding-top: 1em; }
  	.buttonStyle { text-align: center; }
  </style>
</head>

<body>
<?php
require("includes/isSQLInject.php");
require("includes/CheckURLandFORMscope.php");
// include class
include("FormValidatorClass.php");

class myValidator extends FormValidator
{
      // check whether input is a valid phone number
      function isPhone($field, $msg)
      {
        $value = $this->_getValue($field);
        $pattern = "/^\(?\d{3}\)?(\s|\.|-)?\d{3}(\s|-|\.)?\d{4}$/";
        if(preg_match($pattern, $value))
        {
          return true;
        }
        else
        {
          $this->_errorList[] = array("field" => $field,
    "value" => $value, "msg" => $msg);
          return false;
        }
      }
  
}

// instantiate object
$fv = new myValidator();

// perform some validations:
$fv->isEmpty("name", "Please enter a name");
$fv->isEmpty("phone", "Please enter your phone number.");
$fv->isPhone("phone", "Please enter a valid phone number in format NNN-NNN-NNNN.");
//$fv->isNumber("age", "Please enter a valid age");
$fv->isInteger("age", "Please enter an age which is a whole number.");
$fv->isWithinRange("age", "Please enter an age within the numeric range 1-99", 1, 99);
$fv->isEmpty("sex", "Please enter your sex");
$fv->isEmpty("stype", "Please select one of the listed sandwich types");
$fv->isEmpty("sfill", "Please select one or more of the listed sandwich fillings");
//$fv->isNumber("price", "Please enter a numeric price.");
$fv->isFloat("price", "Please enter a price which is a decimal number.");
$fv->isEmailAddress("email", "Please enter a valid e-mail address.");

if ($fv->isError())
{
  echo "  <div id='error_container'>\n";
  echo $fv->getFormattedErrorList();
  echo "  <a class='overlap_bottom' href='' onclick='history.back();'>Try again  </a>\n";
  echo "  </div>";
}
else
{
  // do something useful with the data
  echo "<div style='width: 700px; border: 1px solid gray; border-radius: 2em; margin: 0 auto; padding:1em; font-family: Arial, sans-serif;'>\n";
  echo "<h4>Data OK</h4>\n";
  echo "<pre>\n";
  print_r($_POST);
  echo "</pre>\n";
  echo "</div>\n";
}

?>
</body>
</html>
  

FormValidator Class Documentation

First, here is a portion of the stylesheet that formats the error information that is returned by the method getFormattedErrorList():

#error_container
{
  position: absolute;
  left: 120px;
  top: 170px;
}

.overlap_bottom
{
  position: relative;
  left: 1em;
  top: -1.6em;
}

#fv_error_div
{
  z-index: 3;
  width: 700px; 
  border: 1px solid gray; 
  border-radius: 2em; 
  margin: 0 auto; 
  padding:1em; 
  font-family: Arial, sans-serif;
  background-color: #FDD;
}
  

And now a listing of the methods in the FormValidator Class can be found here.