PHP :: How To Use Serverside Validation


July 23, 2012

PHP :: How To Use Serverside Validation

Where are we?

You know how to get data from a form, and validate it. You know how to use a validation function. Let’s improve the way that’s done. Again.

This lesson’s goals

By the end of this lesson, you should:

  • Know how to have the HTML for the form and the PHP validation code on the same page.
  • Know how to collect error messages in a single variable, rather than treating them all separately.

The form/processor pattern

Up to now, we’ve separated the page with the input form from the page that does validation and processing. Like this:

Pattern so far

Figure 1. Pattern so far

The

.hmtl

page has a

<form>.

The

action 

attribute of the form has the name of the processing page. When the user clicks the

submit

button, the form data is sent to the processing page.

The processing page validates the data. If there is a problem, it shows a message to the user, and suggests going back to the order form again.

If all the form data is OK, the order is processed. This means telling the shipping department to send the order, processing payment, and other businessy things.

A new pattern

But there’s another way of doing things. The new pattern is to put both the form and the server-sidePHP validation code on the same page.

The strangest thing about this is that the page with the form submits data to itself.

A new pattern

Figure 2. A new pattern

This is helpful when you do both client-side and server-side validation, and want to show both types of errors to the user in the same way. The new pattern lets you be more consistent in the way you show errors to users.

The key to this is that the page works in two modes:

  • New input mode: The user wants to fill in the form with some new data.
  • Process input mode: Check data the user has already entered.

The page uses

if 

statements to act differently, depending on which mode it’s in.

What are these “modes” you speak of?

Let’s be sure we know what I mean by “modes” here. You’re used to thinking about modes that are built in to devices. For example, you might have an SUV that works in two-wheel or four-wheel drive. Two different modes. You use a switch (or whatever) to choose the mode you want.

The engineers who designed the vehicle built those modes into it.

Another example is the camera in your cell phone. It can work in still photo mode. Or it can work in video mode, where it shoots movies. You choose the modes you want.

The engineers who designed the cell phone built those modes into it.

But when you write PHP, you are the engineer. You get to create modes yourself. You decide:

  • What the modes are
  • What each one does
  • How each mode is activated

You do this by the way you write your code. There is no special “mode” statement in PHP. The modes are created by the way you put together

if 

statements and other things.

Let’s see how all this works.

What the user sees

Here’s an empty order form, from

order.php.

Empty order form

Figure 3. Empty order form

Suppose the user enters some bad data into

order.php:

Bad data

Figure 4. Bad data

The form data is sent from

order.php to order.php; 

the page sends the form data to itself. Here is what it shows:

Error messages

Figure 5. Error messages

Now, what if the user enters valid data?

Valid data

Figure 6. Valid data

Here is the result:

Order confirmation

Figure 7. Order confirmation

You can try it. Enter different combinations of good and bad data into the fields, and see what you get.

Some code

Here’s order.php.

01.<?php
02.if ( $_POST ) {
03.//There is order data to validate.
04.require 'validation-library.inc';
05.//Warning: Extra characters at the end of validation-library.inc
06.//will break this page!
07.//Get the order amounts.
08.$frisbees = $_POST['frisbees'];
09.$giant_chew_ropes = $_POST['giant_chew_ropes'];
10.//Validate input.
11.$error_message_frisbees = check_number_ordered($frisbees, 15);
12.$error_message_giant_chew_ropes = check_number_ordered($giant_chew_ropes, 10);
13.//Jump if no errors.
14.if ( $error_message_frisbees == '' && $error_message_giant_chew_ropes == '') {
15.$destination_url = "process.php?frisbees=$frisbees&giant_chew_ropes=$giant_chew_ropes";
16.header("Location:$destination_url");
17.exit();
18.}
19.}?><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
20.<html>
21.<head>
22.<title>Order Form</title>
23.<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
24.</head>
25.<body>
26.<h1>Order Form</h1>
27.<?php
28.//Any error messages to display?
29.if ( $error_message_frisbees != '' ) {
30.print "<p>Frisbees: $error_message_frisbees</p>";
31.}
32.if ( $error_message_giant_chew_ropes != '' ) {
33.print "<p>Giant chew ropes: $error_message_giant_chew_ropes</p>";
34.}
35.?>
36.<form method="post" action="order.php">
37.<p>
38.Frisbees:
39.<input type="text" name="frisbees" size="3"
40.<?php
41.if ( $_POST['frisbees'] ) {
42.print ' value="' . $_POST['frisbees'] . '"';
43.}
44.?>
45.>
46.at $8.95 each
47.</p>
48.<p>
49.Giant chew ropes:
50.<input type="text" name="giant_chew_ropes" size="3"
51.<?php
52.if ( $_POST['giant_chew_ropes'] ) {
53.print ' value="' . $_POST['giant_chew_ropes'] . '"';
54.}
55.?>
56.>
57.at $12.95 each
58.</p>
59.<p>
60.<button type="submit">Order</button>
61.</p>
62.</form>
63.</body>
64.</html>
Figure 8. order.php

Line 2:

if ( $_POST ) {

checks whether there is any form data coming in. If there is no post data, then

$_POST

will be empty, which, in PHP, is lihe bring

false.

This is the mode check, if you want to think of it that way. If there is post data, we enter “check input” mode. Otherwise, we’re in “empty form” mode.

We created a validation function on the previous page. We’ll put it in a separate file, and bring it in like this (lines 4):

require 'validation-library.inc';

We’ll talk about the warning in lines 5 and 6 later.

Lines 8 and 9 get the form data into variables, as usual. Here’s one of the lines:

$frisbees = $_POST['frisbees'];

As before, the function

 check_number_ordered()

checks the value passed in, and returns either an error message or a blank string (line 11):

$error_message_frisbees = check_number_ordered($frisbees, 15);

The next step is to check whether there are any errors. There were no errors if both the frisbees value and the giant ropes value were OK.

Here is the code:

14.if ( $error_message_frisbees == '' && $error_message_giant_chew_ropes == '') {
15.$destination_url = "process.php?frisbees=$frisbees&giant_chew_ropes=$giant_chew_ropes";
16.header("Location:$destination_url");
17.exit();
18.}
Part of Figure 8 (again). order.php

Line 14 has the test. Remember that the validation function

check_number_ordered()

returns an empty string. So that if both

$error_message_frisbees and $error_message_giant_chew_ropesare

empty strings, there were no errors.