Web Development

Handling multiple submits in a single form with PHP

Processing form data in PHP is significantly simpler than most other Web programming languages. This simplicity and ease of use makes it possible to do some fairly complex things with forms, including handling multiple submit buttons in the same form.

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.

15 comments
md2811
md2811

I am learning to create my own database and the sample included a form using ADD RECORD which displayed the form at the top of the printed processed data and the DELETE buttons were included at the end of every full entry which was displayed on the same form after the input data. I tried switching the DELETE button to be included next to the ADD RECORD because I want to include an option to delete a record by the id and have the data displayed in a table below the form. This would be for the administrators entering the data. But I also want the entered records to show in a designed table that will appear on the Website. How will I accomplish this?

after8b49
after8b49

Sorry - my inputs don't appear. here they are again (without the start tags) input type='submit' name='up[0]' value='Up'> input type='submit' name='down[0]' value='Down'> input type='submit' name='up[1]' value='Up'> input type='submit' name='down[1]' value='Down'> input type='submit' name='up[2]' value='Up'> input type='submit' name='down[2]' value='Down'>

after8b49
after8b49

Many thanks for the article. I have often come across the situation of wanting multiple submit buttons on a single form. In fact, sometimes I want several submit buttons to have the same name and the same value. Why? Well, like your example, I want different buttons to perform different actions. But what if you have several items in a table, all in one form, and each item can have several actions? You want to gather the data for all items (say you allow text inputs to be changed for several items at a time), but still want to know which button for which item was clicked. Your article helped me find the answer. You can have an array of submit buttons with the same name and same value, as follows (in this case two arrays of buttons)... Using is_array and array_keys, you can find which one was clicked, like this if (is_array($_POST["up"])){ $myup = array_keys($_POST["up"]); echo "My up is ".$myup[0].""; } if (is_array($_POST["down"])){ $mydown = array_keys($_POST["down"]); echo "My down is ".$mydown[0].""; } There are a couple of things to note here. You need to test if 'up' or 'down' (in my example) has been posted - only one submit button can be clicked, so either 'up' or 'down' will exist, but not both. Do that with is_array(). Second thing to note is that the array size will always be 1 (whichever button has been clicked) - and array_keys will tell you which one. Ask what the array key is for the first (and only) array element (i.e. $myup[0] or $mydown[0] in my example) and this will be the button that was clicked. I have wanted to be able to do this for ages, and I finally worked it out, thanks to your article. Many thanks

knikaido
knikaido

[input type="submit" name="calculate" value="add"] [input type="submit" name="calculate" value="minus"] [input type="submit" name="calculate" value="multiply"] I want to change it into: [input type="button" name="calculate" value="add" onclick="saveForm(); [input type="button" name="calculate" value="minus" onclick="saveForm2(); [input type="button" name="calculate" value="multiply" onclick="saveForm3(); return false;"] I've tried it but always return nothing.. I got the post value is NULL.. can u help me? thanks

modernvox
modernvox

Thanks Man..I searched Hi and Lo for this. This article saved my sanity. If you ever come to Massachusetts, USA let's hang out! B. Regards, Mike

olevski90
olevski90

I didn't know you could do this at all. I am working on a similar project which has a form with multiple submit buttons. I had no idea at all that you can figure out which button was clicked to call the form so easily. I was going to add radio buttons and go back to one submit button, but now I will be able to pull it off. THANK YOU SO MUCH!!!!

VinnieCool
VinnieCool

Is there a simple way to do a regex search on array keys. I want to name multiple submits as btn_edit, btn_delete, btn_save etc. So by doing a regex search for "btn*" I can know the action e.g. "edit.

nirbhay.saini
nirbhay.saini

I want to try login page in one script such regiser login logout and forgot password with switch case how it possible nirbhay.saini@indiatimes.com

chanchal.sakarde
chanchal.sakarde

Can i Have Multiple form action on a single page to pass POST data to different page

harsha1485
harsha1485

Good Tutorial...Helped me a lot....Thank You...

baby.chahal
baby.chahal

pls slove this if we make a button which use for deleted data in while{ }case, wht's code

ericreich00
ericreich00

I have a form to allow our visitors to download a sample of our coursware. We want the submit button to handle two functions. 1. submit the info as normal (this is already completed) 2. open the page for the download link. Thank you, Eric Reich

md2811
md2811

What I tried didn't work.

after8b49
after8b49

My guess is that you have three forms, but want the buttons to submit them to all be in one place. Is that why you don't just have a separate submit button for each form? You have inputs that look like submit buttons, but actually launch javascript functions, is that right? I may be wrong, but as far as I know a submit button within form tags will automatically submit any inputs within the form tags, whereas using an input type of button will just run whatever code you specify with the onClick command - it is not associated with any input data, hence posts nothing.

afif88
afif88

Thank ! great tutorial! found multiple graphic submit button particularly useful!