Processing form data in PHP is significantly simpler than in
most other Web programming languages—a fact you’re undoubtedly already aware of
if you’ve been using the language for a while. This simplicity and ease of use
makes it possible to do some fairly complex things with forms…including the
topic of today’s discussion, handling different actions through multiple submit
buttons in the same form.
Why multiple submits?
Before I get started, though, let me answer the obvious
question: Since most forms are perfectly happy with a single submit button, why
would anyone ever need two (or more)?
The best way to explain such a need is with an actual
example from the last project I worked on. In that project, I was tasked with
building an inventory system for a book-lending library. The book titles were
all stored in a database, and administrators could use a browser-based
interface to view the record for any book and then perform one of four actions
on that record: check out to a member, check in from a member, mark as missing,
and mark as sold.
All these activities were handled through a single form,
which had buttons corresponding to the actions above. Depending on which button
was clicked, the data entered in the form was processed in a different way
(check in/out was connected with membership records; mark as missing/sold
updated inventory tables). Since a form can only have a single action, the same
PHP script had to handle all four tasks, by identifying which button had been
clicked and executing the appropriate code branch. Thus, a need arose for a
single form carrying multiple submit buttons, and a form-processing script with
the intelligence to distinguish between each one.
A single-button form
I’ll begin with a simple example—a single form with a single
submit button—to ensure you are clear on the basics and to provide a base for
the more-complex example. Here is a form:
<html><head>Single-button form</head>
<body>
<form action=”processor.php” method=”post”> Enter a number: <input type=”text” name=”number” size=”3″> <br>
<input type=”submit” name=”submit”> </form>
</body>
</html>
And here is the processor.php script that gets invoked on
submission:
<?php
// check for submission
// retrieve value from posted data
if ($_POST[‘submit’])
{
echo “You entered the number ” . $_POST[‘number’]; }
?>
When a form is submitted to a PHP script, PHP automatically
creates a special $_POST or $_GET associative array, depending on which method
of submission was used (I’ll assume POST throughout this tutorial). Values
entered into the form input fields are automatically converted to key-value
pairs in this array and can then be accessed using regular array notation.
Pay special attention to how the submit button is handled in
the above script. When the form is submitted, the submit button itself becomes
an element in the $_POST array, with a key corresponding to its
“name”. This is clearly visible by adding the line:
print_r($_POST);
to the end of the PHP script above. You can look inside the
array and clearly see the correspondence between the form controls and their
PHP representations.
Now let’s take a look at how to handle multi-button
forms.
Branching with if/else
Let’s now make things a bit more complicated by adding a
second submit button to the form:
<html><head>Multi-button form</head>
<body>
<form action=”processor.php” method=”post”> Enter a number: <input type=”text” name=”number” size=”3″> <br>
<input type=”submit” name=”add” value=”Add 10″>
<input type=”submit” name=”subtract” value=”Subtract 10″> </form>
</body>
</html>
Since both submit buttons will invoke the same PHP form
processor, that PHP script must be revised to “know” which one was
clicked so it can respond appropriately.
Since you already know that the submit button appears in the
$_POST PHP array and is keyed by its “name” attribute, it’s simple to
(1) give each submit button in the form a unique name and (2) write a simple
“if” test at the top of the PHP form processor to see which of the
two keys appears in the $_POST array and branch the code appropriately. That’s
exactly what the script below does:
<?php
// check which button was clicked
// perform calculation
if ($_POST[‘add’])
{
echo $_POST[‘number’] . ” + 10 = ” . ($_POST[‘number’]+10); } else if ($_POST[‘subtract’]) {
echo $_POST[‘number’] . ” – 10 = ” . ($_POST[‘number’]-10); }
?>
If you have a bunch of submits, a good idea is to use a switch/case
statement to handle the different code branches more efficiently.
Branching with switch/case
In the previous example, I distinguished between buttons by
using different name attributes for the submit buttons in the form. An
alternative is giving all the submit buttons the same name, but different values:
<html><head>Multi-button from with switch/case</head>
<body>
<form action=”processor.php” method=”post”> Enter a number: <input type=”text” name=”number_1″ size=”3″> <br> Enter another number: <input type=”text” name=”number_2″ size=”3″> <br>
<input type=”submit” name=”calculate” value=”add”>
<input type=”submit” name=”calculate” value=”subtract”>
<input type=”submit” name=”calculate” value=”multiply”> </form>
</body>
</html>
The processing script needs to check the value of the
$_POST[‘calculate’] element, and branch the code appropriately. The most efficient
way to do this is with a switch-case
statement, as follows:
<?php
// branch on the basis of ‘calculate’ value
switch ($_POST[‘calculate’]) {
// if calculate => add
case ‘add’:
echo $_POST[‘number_1’] . ” + ” . $_POST[‘number_2’] . ” = ” . ($_POST[‘number_1’]+$_POST[‘number_2’]);
break;
// if calculate => subtract
case ‘subtract’:
echo $_POST[‘number_1’] . ” – ” . $_POST[‘number_2’] . ” = ” . ($_POST[‘number_1’]-$_POST[‘number_2’]);
break;
// if calculate => multiply
case ‘multiply’:
echo $_POST[‘number_1’] . ” x ” . $_POST[‘number_2’] . ” = ” . ($_POST[‘number_1’]*$_POST[‘number_2’]);
break;
}
?>
Depending on which button gets clicked, the appropriate
value is passed to the processing script and the corresponding “case”
block is invoked. If you have a large number of submit buttons to deal with, this
approach is easier to read and understand than multiple if-else blocks.
But what about the case where you’ve got graphical submit buttons
instead of text-based?
Using graphical submit buttons
A minor twist in the tale comes if you use a graphical
submit button, as in the following simple form:
<html><head>Graphical submit button</head>
<body>
<form action=”processor.php” method=”post”> Search for: <input type=”text” name=”q”>
<input type=”image” name=”go” src=”/images/go.gif”> </form>
</body>
</html>
When this form is sent to PHP for processing, look what the
$_POST array contains:
Array
(
[q] => magpie
[go_x] => 13
[go_y] => 13
)
Because it’s a graphical button, PHP actually tracks the
mouse coordinates of the mouse click and creates two elements in the result
array to store those coordinates. The elements are named [button_name]_x and [button_name]_y
respectively.
Why is this important? Well if you’d been using an if() test keyed on the
submit control’s “name” the test would have failed because
instead of creating a single element accessible through $_POST[‘go’], PHP actually
created two elements named $_POST[‘go_x’]
and $_POST[‘go_y’] respectively. Make
a mental note of this for future reference; it might save you some time when
things don’t work as expected.
So now, what happens if you have multiple graphical submit buttons
in your form:
<html><head>Multiple graphical submit buttons</head>
<body>
<form action=”processor.php” method=”post”> Enter part number: <input type=”text” name=”part”> <br>
<input type=”image” name=”view” src=”/images/view.gif”>
<input type=”image” name=”edit” src=”/images/edit.gif”>
<input type=”image” name=”delete” src=”/images/delete.gif”>
<input type=”image” name=”order” src=”/images/order.gif”> </form>
</body>
</html>
Your PHP script would need to contain multiple branches, something
like this:
<?php
if ($_POST[‘view_x’]) {
// code to view record
} else if ($_POST[‘edit_x’]) {
// code to edit record
} else if ($_POST[‘delete_x’]) {
// code to delete record
} else if ($_POST[‘order_x’]) {
// code to place an order
}
?>
Finally, here’s a real-life example to tie it all up. This
example consists of a dynamically-generated form with a list of e-mail
addresses from a user’s address book. The user can select one or more addresses
from this list and then add them to a whitelist or a blacklist; (s)he can also
remove them from the address book. The form contains three action buttons
corresponding to these three tasks. Take a look at
Listing A.
Notice that, in this case, the submit buttons are named like
PHP array elements, with the key representing the action. When the form is
submitted, this naming scheme will cause a single-element array to be created
within the $_POST array; this can then be used to identify the action and
execute the appropriate code branch using a switch-case statement, as you can
see in Listing B.