Overview

The PHP Validation script is a set of validation rules which lets you add server-side validation to your forms quickly and with as little effort as possible. The script checks the values that a user has entered into your form, and if it doesn’t meet the criteria specified (e.g. they failed to enter a value, or they entered a fake email address), they are returned to the original form with a list of all the offending fields. It requires PHP 4 or later.

Click on the various links in the box above to get instructions on how to add it to your form, see and view the PHP for a demonstration form and get a list of all available validation rules. The demonstration page contains all the validation options currently offered by the script. Version 2.0 (Dec 2006) includes some additional validation rules (alphanumeric test, improved range and length tests). It is backward compatible with earlier versions. Many thanks to Mihai Ionescu and Nathan Howard for contributing their code. The 2.3.1 release fixes a bug noticed by Khalid Hanif with the reg_exp option. Thanks Khalid!

I’ve tried to make this script as simple to integrate as possible, but these help pages are included here as a handy reference and starting point.

How to add validation to your form

Okay, let’s get started! Here are the steps you’ll need to do to get it working with your form. We’ll go into more detail in the later pages – this page is mainly just to give you a general sense of how it fits together.

1. Download and upload the PHP validation script (validation.php) to your web server and include() or require() that file via PHP in your form page. Note: your form will need to be a .php page.

2. Direct your form to submit its contents to itself using the action=”” attribute. When the form successfully passes your validation rules, you can redirect via PHP to whatever page you want the user to see next. If it fails, you can output the errors directly in the form page for the user to fix.

3. Add your form-specific validation rules to the top of your form page before the opening tag. These validation rules are basically a LIST (or an array for the technically-literate), saying which form fields need to validated, in what way, and what errors should be displayed to the user if they’re not filled in properly.

4. Add some display code into your page which will output any errors that occur.

1
2
3
4
5
6
7
8
9
10
11
12
<?php    
// if $errors is not empty, the form must have failed one or more validation
// tests. Loop through each and display them on the page for the user
if (!empty($errors))
{
  echo "<div class='error'>Please fix the following errors:\n<ul>";
  foreach ($errors as $error)
    echo "<li>$error</li>\n";
     
  echo "</ul></div>";
}    
?>

Demo form and explanation

Probably the best way to understand how the script works is to see an example. Take a look at the demonstration page. Here’s the PHP validation code in that page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
$errors = array(); // set the errors array to empty, by default
$fields = array(); // stores the field values
$message = "";
 
if (isset($_POST["submit"]))
{
   // import the validation library
   require("validation.php");
 
   $rules = array(); // stores the validation rules
 
   // standard form fields
   $rules[] = "required,user_name,This field is required.";
   $rules[] = "required,email,Please enter your email address.";
   $rules[] = "valid_email,email,Please enter a valid email address.";
   
   // date fields
   $rules[] = "valid_date,any_date_month,any_date_day,any_date_year,any_date,Please enter a valid date.";
   $rules[] = "valid_date,later_date_month,later_date_day,later_date_year,later_date,Please enter an date later than today.";
   
   // Numbers / alphanumeric fields
   $rules[] = "required,any_integer,Please enter an integer.";
   $rules[] = "digits_only,any_integer,This field may only contain digits.";
   $rules[] = "digits_only,number_range,This field may only contain digits.";
   $rules[] = "range=1-100,number_range,Please enter a number between 1 and 100.";
   $rules[] = "range>100,number_range_greater_than,Please enter a number greater than 100.";
   $rules[] = "range>=100,number_range_greater_than_or_equal,Please enter a number greater than or equal to 100.";
   $rules[] = "range<100,number_range_less_than,Please enter a number less than 100.";
   $rules[] = "range<=100,number_range_less_than_or_equal,Please enter a number less than or equal to 100.";
   $rules[] = "letters_only,letter_field,Please only enter letters (a-Z) in this field.";
   $rules[] = "required,alpha_field,Please enter an alphanumeric (0-9 a-Z) string.";
   $rules[] = "is_alpha,alpha_field,Please only enter alphanumeric characters (0-9 a-Z) in this field.";
   $rules[] = "custom_alpha,custom_alpha_field1,LLL-VVV,Please enter a string of form LLL-VVV - where L is an uppercase "
      . "letter and V is an uppercase vowel.";
   $rules[] = "custom_alpha,custom_alpha_field2,DDxxx,Please enter a string of form DDxxx.";
   $rules[] = "custom_alpha,custom_alpha_field3,EEXX,Please enter a string of form EEXX.";
   $rules[] = "custom_alpha,custom_alpha_field4,VVvvllFF,Please enter a string of form VVvvllFF.";
   $rules[] = "custom_alpha,custom_alpha_field5,#XccccCCCC,Please enter a string of form #XccccCCCC.";
   $rules[] = "reg_exp,reg_exp_field1,^\s*(red|orange|yellow|green|blue|indigo|violet|pink|white)\s*$,Please enter your "
      . "favourite colour in lowercase (e.g. \"red\" or \"blue\")";
   $rules[] = "required,reg_exp_field2,Please enter your favourite colour (e.g. \"red\" or \"blue\")";
   $rules[] = "reg_exp,reg_exp_field2,^\s*(red|orange|yellow|green|blue|indigo|violet|pink|white)\s*$,i,Please enter your "
      . "favourite colour (e.g. \"red\" or \"blue\")";
   
   // Length of field input
   $rules[] = "length=2,char_length,Please enter a value that is exactly two characters long.";
   $rules[] = "length=3-5,char_length_range,Please enter a value that is between 3 and 5 characters in length.";
   $rules[] = "length>5,char_length_greater_than,Please enter a value that is over 5 characters long.";
   $rules[] = "length>=5,char_length_greater_than_or_equal,Please enter a value that is at least 5 characters long.";
   $rules[] = "length<5,char_length_less_than,Please enter a value that is less than 5 characters long.";
   $rules[] = "length<=5,char_length_less_than_or_equal,Please enter a value that is less than or equal to 5 characters.";
   
   // password fields
   $rules[] = "required,password,Please enter a password.";
   $rules[] = "same_as,password,password_2,Please ensure the passwords you enter are the same.";
   
   // conditional (if-else) fields
   $rules[] = "required,gender,Please enter your gender.";
   $rules[] = "if:gender=male,required,male_question,Please enter the name of your favourite Care Bear.";
   $rules[] = "if:gender=female,required,female_question,Please indicate what max weight you can bench.";
   
   $errors = validateFields($_POST, $rules);
   
   // if there were errors, re-populate the form fields
   if (!empty($errors))
   {
      $fields = $_POST;
   }
   
   // no errors! redirect the user to the thankyou page (or whatever)
   else
   {
      // for illustration purposes.
      $message = "All fields have been validated successfully!";
       
      // here you would either email the form contents to someone or store it in a database.
      // To redirect to a "thankyou" page, you'd just do this:
      // header("Location: thanks.php");
   }
}

The overall logic of the code is simple: if the user has clicked the submit button (with the name=”submit” attribute), it submits the contents of the form to the same page. Then, the if (isset($_POST[“submit”])) test returns true, and it executes the code in that if-block.

Each rules[] = “…” line adds a new validation rule into the rules list. Calling the validateFields() function passes in the rules you’ve made up, and returns a list of errors that occurred. These errors are then outputted to the page for the user to fix.

Each of the validation rules are all of the following form:

1
"[if:FIELDNAME=VALUE,]REQUIREMENT,fieldname[,fieldname2[,fieldname3,date_flag]],error message"

The square bracket [] notation indicates that the contents are optional. Note: you cannot include commas in the error messages. This will currently cause the alerted messages to be truncated.

Available Validation Rules

To recap: the validation rules are all of the following form:

1
"[if:FIELDNAME=VALUE,]REQUIREMENT,fieldname[,fieldname2[,fieldname3,date_flag]],error&nbsp;message"

The square bracket [] notation indicates that the contents are optional. Note: you cannot
include commas in the error messages. This will currently cause the alerted messages to be
truncated.

if:FIELDNAME=VALUE, or
if:FIELDNAME!=VALUE,

This allows us to only validate a field only if a fieldname FIELDNAME has – or doesn’t have –
a value VALUE. This option allows for nesting; i.e. you can have multiple if clauses, separated
by a comma. They will be examined in the order in which they appear in the line.

REQUIREMENT

Valid REQUIREMENT strings are:

required field must be filled in
digits_only field must contain digits only
length=X field has to be X characters long
length=X-Y field has to be between X and Y (inclusive) characters long
length>X field has to be greater than X characters long
length>=X field has to be greater than or equal to X characters long
length<X field has to be less than X characters long
length<=X field has to be less than or equal to X characters long
valid_email field has to be valid email address
valid_date field has to be a valid date

fieldname: MONTH field
fieldname2: DAY field
fieldname3: YEAR field
date_flag: “later_date” / “any_date”

same_as fieldname is the same as fieldname2 (for password comparison)
range=X-Y field must be a number between the range of X and Y inclusive
range>X field has to be a number greater than X
range>=X field has to be a number greater than or equal to X
range<X field has to be a number less than X
range<=X field has to be a number less than or equal to X
is_alpha field has to be an alphanumeric character (anything between 0-9, a-Z)
letters_only field has to be a letter, a-Z
custom_alpha This option is a layman’s version of the reg_exp rule and offers more control
than the letters_only rule. It lets you check that a field is formatted in a very
specific way. For example:
1
2
// this requires the "field_name" form field be of the form: {any letter}{uc letter}{lc consonant}{lc consonant}
$rules[] = "custom_alpha,field_name,DLcc,Error message";

Here’s all the different formatting options and what each character means:

L An uppercase letter. V An uppercase vowel.
l A lowercase letter. v A lowercase vowel.
D A letter (upper or lower) F A vowel (upper or lower)
C An uppercase Consonant x Any number, 0-9
c A lowercase consonant X Any number, 1-9
E A consonant (upper or lower)

Any characters included in the string that aren’t in the above list are simply required
as they are. So if your rules was CVC-VCV, the user would have to enter consonant, vowel, consonant
followed by a dash, followed by vowel, consonant, vowel.

reg_exp This option is for programmers only. It lets you validate a field by a regular expression.
This rule comes in two forms: one with a RegExp flag (like “g” for global, “i” for
case-insensitive etc.) and one without. Unless you expressly need to supply a flag, just
use the first form.
1
2
3
4
// format #1
$rules[] = "reg_exp,field_name,REGEXP,Error message";
// format #1
$rules[] = "reg_exp,field_name,REGEXP,Flag(s),Error message";

Note: be sure to double-escape regexp escape characters. e.g. to match whitespace, the \s needs to be \\s.

Notes: With both digits_only and valid_email options, if the empty string is passed in it
won’t generate an error, thus allowing validation of non-required fields. So, if you want a
field to be a valid email address, provide validation for both “required” and “valid_email”.

Other Comments

JS vs PHP Validation

As mentioned earlier, the PHP validation script was written to be identical to the RSV JS sister script, so you can just copy and paste the rules from one to the other. The only validation rule that doesn’t appear in the PHP Validation is the function rule. Due to the way the JavaScript validation works – rule by rule, showing a single popup error at a time – the function rule was needed to let you leave the standard control flow execution and run your own function(s). With PHP, this isn’t required: you can simply embed the custom scripts directly in the PHP code.

Re-entering form values

One question I get asked a lot is concerning re-entering the form values when the user fails to enter something in correctly. By default, the fields will not have their values re-entered. This is a natural result of the “stateless” aspect of the web: information is not retained from one page to the next unless you explicitly account for it. To fix this, you will need to explicitly set the value to what the user entered. For example:

1
<input type="text" name="first_name" value="<?=htmlspecialchars($_POST['first_name'])?>" />

Download

This project is now found on github. You can download it from there.