Developer

Learn how to create a multipage form

When you're working with PHP, it's possible to create a multipage form. Here's how.

By David Sklar and Adam Trachtenberg

Of course, there's really no such thing as "all there is." After all, if you can have forms on one page, why can't you have forms that span multiple pages?

Unfortunately, HTTP doesn't make it easy for us to transfer data from one page to another. That's because there's no built-in mechanism within the protocol to define a notion of a series of pages. Luckily, with a few clever tricks and the help of some handy functions in PHP, we'll work around this limitation without too much of a struggle. The key idea in this section is that we'll save all the input from a previous page as hidden variables inside the form on the following page. Because the code passes along the information as we string through the screens, each form always contains the data from its predecessors. This solution is a little kludgy, but it's by far the simplest method—and it doesn't require us to use a database or cookies.

Not surprisingly, we'll extend our use of the $state variable to accommodate this feature. That's really why we went through the trouble of introducing that technique, when there are some slightly simpler ways to handle forms of just one page.

For convenience, let's reuse the form example from before. But this time, instead of placing the name with the important questions about cheese, we'll split them up into two pages.

As a result, now we'll have three functions instead of just two. In addition, we'll rename them a bit to reflect the change in content. display_form() is now display_name().

<?php
function display_name() {
 global $PHP_SELF;

?>
<FORM TARGET="<?php echo $PHP_SELF; ?>" METHOD=GET>
Name: <INPUT TYPE=TEXT NAME="name"><BR>
<INPUT TYPE=HIDDEN NAME="stage" VALUE="cheese">
<INPUT TYPE=SUBMIT VALUE="Thanks!">
</FORM>
<?php
}
?>

This is identical to the earlier function, but we've snipped out the latter questions and changed the name of the next stage to cheese to more accurately describe what's next.

Now comes display_cheese().

<?php
function display_cheese() {
  global $PHP_SELF;
  global $name;

?>
<FORM TARGET="<?php echo $PHP_SELF; ?>" METHOD=GET>
Favorite Cheese: <INPUT TYPE=RADIO NAME="cheese" VALUE="brie">Very soft French Brie
                 <INPUT TYPE=RADIO NAME="cheese" VALUE="cheddar">Farmhouse English Cheddar
                 <INPUT TYPE=RADIO NAME="cheese" VALUE="mozzarella">Italian Buffalo Mozzarella

Favorite Times to Eat Cheese:                  <INPUT TYPE=CHECKBOX NAME="times[]" VALUE="m">Morning
                 <INPUT TYPE=CHECKBOX NAME="times[]" VALUE="n">Noon
                 <INPUT TYPE=CHECKBOX NAME="times[]" VALUE="d">Dinner
                 <INPUT TYPE=CHECKBOX NAME="times[]" VALUE="l">Late night

<INPUT TYPE=HIDDEN NAME="name" VALUE="<?php echo htmlspecialchars($name); ?>">
<INPUT TYPE=HIDDEN NAME="stage" VALUE="results">
<INPUT TYPE=SUBMIT VALUE="Thanks!">
</FORM>
<?php
}
?>

Again, the code above should look very familiar. We haven't made any unexpected modifications from before, except that right before we print the hidden stage element, we print the name and value of $name, our previous piece of data. We also don't just print the value directly, but run it through a PHP function called htmlspecialchars(). In HTML, there are four characters that aren't supposed to be used except as markup: <, >, ", and &. For that reason, in order to make sure we don't confuse the browser, we run $name through htmlspecialchars(), so someone whose name was formerly "Bret & Jeff" becomes "Brett & Jeff."

Now, when this new form is submitted, we won't lose any information.

As a result of this trick, we don't need to change one letter of process_form(). In fact, we'll even keep the name of the function the same. And, we'll need to add just one new line to our page-display logic.

<?php
if (empty($stage)) { display_name(); }
elseif ($stage == 'cheese') { display_cheese(); }
else { process_form(); }
?>

See that? All we did was sneak in an elseif in the middle of our two statements. That's the beauty of using $stage. If we want to add additional pages, we just need to write a new function to display what we want and a single line to control when it's displayed.

David Sklar is the CTO of Student.Net Publishing.

Adam Trachtenberg is the Vice President for Production of Student.Net Publishing.

Editor's Picks

Free Newsletters, In your Inbox