Web Development

Secure your Web applications by validating user input with PHP

Input validation is an important part of securing your Web application and for creating a more robust technological system.

Most experienced Web developers are acutely aware that the single most vulnerable point of any Web application is its forms. This is because Web forms typically directly interface with the application's database or calculation algorithms, and so a small error in user input can easily cascade into widespread data corruption problems.

For this reason, input validation is an important part of securing your Web application and creating a more robust technological system. If you use PHP (and you should), this task is significantly simplified by the PEAR Validate class, which provides ready-made methods for common user validation tasks.

To see this class in action, begin by downloading and installing it to your system. You can install the package manually, extracting its contents to your PEAR base directory, or by using the PEAR installer.

Note: Listing A and B are available in manageable text form included with the download file.

The Validate class comes with a number of built-in input validation methods, which are described in Table A.

Table A


Method

What It Does

Example Usage

number($input, $opts)

Tests if input is a number. Can also check if numeric input falls within a specific range.

<?php
// check if input is a number
echo $validate->number("11") ? "true" : "false";

// check if input lies between 1 and 99
echo $validate->number("110", array("min" => 1, "max" => "99")) ? "true" : "false";
?>
email($input)

Tests if input is a valid e-mail address.

<?php
// check if input is an e-mail address
echo $validate->email("me@example.com") ? "true" : "false";
?>
string($input, $opts)

Tests if input is a string. Can also check if string conforms to a specific pattern or falls within a specific character limit.

<?php
// check if input is a string
echo $validate->string("hello") ? "true" : "false";

// check if input is between 2 and 4 characters long
echo $validate->string("boo", array("min_length" => 2, "max_length" => 4)) ? "true" : "false";
?>
uri($input)

Tests if input is a valid URL.

<?php
// check if input is a URL
echo $validate->uri("http://www.builder.com") ? "true" : "false";
?>
date($input, $opts)

Tests if input is a valid date.

<?php
// check if input is a valid date in the form "DD-MM-YY"
echo $validate->date("06-07-08", array("format" => "%d-%m-%y")) ? "true" : "false";
?>

So, if you need to test if a particular chunk of data conforms to, say, the format for an e-mail address, all you need to do is pass it to Validate'semail() method, which will check it for you and return a true/false value. You can use this value to display an error, halt further execution of the script, or write to an error log.

To see how this plays out in the real world, let's create a simple HTML form and then use Validate to test the integrity of the data entered into it. Begin by creating the simple HTML form shown in Listing A.

Listing A


<html>
<head></head>
<body>
<h2>Enter your comments</h2>
<i>Fields marked with a * are mandatory</i>
<p />

<form action="validate.php" method="post">
Name *<br />
<input type="text" name="name">
<p />

Age *<br />
<input type="text" name="age" size="4">
<p />

E-mail address *<br />
<input type="text" name="e-mail">
<p />

Web site <br />
<input type="text" name="url">
<p />

Comments *<br />
<textarea name="comments"></textarea>
<p />
<input type="submit" name="submit" value="Send">
</form>

</body>
</html>

As you can see, this form contains a number of fields for different types of data. Most of the fields are mandatory. The problem, therefore, is to ensure that the rules (both implicit and explicit) stated in the form are adhered to by users.

To do this, create the following PHP validation script (Listing B) and save it under your Web server's document root.

Listing B


<html>
<head></head>
<body>

<?php
// include class
include("Validate.php");

// initialize input validator
$validate = new Validate();

// initialize error array
$errors = array();

// extract POST-ed variables
extract($_POST);

// check name field
if (!$validate->string($name, array("min_length" => 1))) {
    $errors[] = "Error in NAME field";
}

// check age field, ensure age is between 1 and 99
if (!$validate->number($age, array("min" => 1, "max" => 99))) {
    $errors[] = "Error in AGE field";
}

// check e-mail address format
if (!$validate->e-mail($e-mail)) {
    $errors[] = "Error in E-MAIL field";
}

// if URL supplied, check URL format
if ($validate->string($url, array("min_length" => 1))
 && !$validate->uri($url)) {
    $errors[] = "Error in URL field";   
}

// check comment field
if (!$validate->string($comments, array("min_length" => 1))) {
    $errors[] = "Error in COMMENTS field";
}

// test error array to see if any errors generated
// if so, display error messages
if (sizeof($errors) > 0) {
    echo "Your form could not be processed
because of one or more errors (listed below): <br />";
    echo "<ul>";
    foreach ($errors as $e) {
        echo "<li>$e</li>";
    }
    echo "</ul>";
// if no errors
// do something
// e-mail the comment, or save it to a database
// display a success message
} else {
    echo "Thank you, your comments have been recorded";
}
?>

</body>
</html>

Here, the values entered into the form are converted into regular PHP variables using the extract() function. Next, the Validate class is used to test each variable to see if it is in the correct format, as follows:

  • The "Name" field (required) is tested by checking for the presence of at least a one-character string via the string() method.
  • The "Age" field (required) is tested by checking for the presence of a number between 1 and 99 via the number() method.
  • The "E-mail address" field (required) is tested with the email() method.
  • The "Web site" field (optional) is first tested with the string() method to see if it contains any data; if it does, the format of the URL is tested via the url() method.
  • The "Comments" field (required) is tested by checking for the presence of at least a one-character string via the string() method.

In the event that any of these Validate methods returns false, a new element containing the corresponding error message is added to the $errors array. Once all the validation routines are complete, the $errors array is checked and error messages (if any) are displayed to the user. If no error messages exist within the $errors array, it means that the data is suitable for further usage, such as transmission via e-mail or injection into a storage system or calculation.

As you can see, the Validate class can simplify the task of validating user input. Hopefully, you'll find it useful the next time you sit down to code a Web form. Have fun!

0 comments

Editor's Picks