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!