Form Handling
HTML form controls allow users to input data, make selections and provide a mechanism by which users interact with a web page. A form is useful to the extent that it is backed by a processing script coded on a web page or by a program running on the web server. This tutorial discusses how PHP, like other server-side programming languages, interacts with forms to respond to user input.
Information entered onto a form is submitted for processing by clicking the form's submit button, <input type="submit">
. The information in the form fields is then transmitted to the page identified in the ACTION attribute of the <form>
tag. When this URL request and the accompanying form data arrive at the server, the targeted page is retrieved and the data are made available to it for processing.
Name/Value Pairs
Data from a form are transmitted to the server as a series of name/value pairs. This means that the name of each form element (as appearing in the name attribute of the tag) is associated with the value of that element (as typed or selected by the user). The name/value format used for transmission is name=value. There are as many of these name/value pairs as there are elements on the form, and the pairs are concatenated with ampersands (&) to form a text string that resembles the following:
name1=value1&name2=value2&name3=value3....
Any blank spaces appearing in the names or values are substituted with the plus (+) character to form a non-breaking string of name/value pairs. In the current application assume that the user entered the account "myaccount" and the password "xyzzy". The resulting name/value string delivered to the server would be:
account=myaccount&password=xyzzy&submitButton=Submit
Note that both field and button names and values are transmitted. Although shown here in the same order in which the elements appear on the form, there is no guarantee that the order of the name/value pairs that arrive at the server will be the same as it is on the form.
PHP includes three types of form handling variables for storing and processing user form input: $_GET, $_POST, and $_REQUEST. Recall from Section 3-2 Array Variables that these are actually associative arrays of values. These variables are also referred to as superglobals. This simply means that it is available in all scopes throughout a script.
- $_GET[] - an associative array containing any values provided to a script through a form's GET method.
- $_POST[] - an associative array containing any values provided to a script through a form's POST method.
- $_REQUEST[] - an associative array containing any values provided to a script through a form's POST and GET method. Generally, the $_REQUEST[] array is the preferred way of retrieving form values since it contains all of the form's values regardless of whether the POST or GET method is used.
The following example shows a typical HTML form page that can be processed by PHP:
form_page.html
<!DOCTYPE html>
<html>
<head>
<title>A Web Page</title>
</head>
<body>
<form action="process.php" method="post">
<fieldset>
<table>
<tr>
<td>First Name: </td>
<td><input type="text" name="fname" value="John"></td>
</tr>
<tr>
<td>Last Name: </td>
<td><input type="text" name="lname" value="Smith"></td>
</tr>
<tr>
<td>City: </td>
<td><input type="text" name="city" value="Atlanta"></td>
</tr>
<tr>
<td>State: </td>
<td><input type="text" name="state" value="Georgia"></td>
</tr>
<tr>
<td>Message:</td>
<td><textarea name="message" cols="30" rows="5">I like PHP.</textarea></td>
</tr>
<tr>
<td>:</td>
<td><input type="submit" name="submit" value="Submit Data"></td>
</tr>
</table>
</fieldset>
</form>
</body>
</html>
Below, the form is displayed and the user enters data to be processed:
First Name:
Last Name:
City:
State:
Message:
When the submit button in the above example is clicked, all of the form data entered by the user is passed to the page, process.php, for processing. Since this form is using the POST method, all form data is passed using the PHP $_POST variable. Each input control is uniquely identified by the value assigned to its name attribute. The form control's name attribute value becomes the index value of the $_POST array. The form page, PHPForm.htm, passes data using the following PHP $_POST variables:
$_REQUEST["fname"] ="John";
$_REQUEST["lname"] = "Smith";
$_REQUEST["city"] = "Atlanta";
$_REQUEST["state"] = "Georgia";
$_REQUEST["message"] = "I like PHP.";
Since the PHP $_POST, $_GET, and $_REQUEST arrays use the value associated with the form control's name attribute, it is important that all form elements be assigned a unique name value.
The HTML form page above is processed by the page process.php shown below: Data entered into the form is passed using the $_POST variable to a PHP script that displays the information to the browser window:
process.php
<?php
if (isset($_POST['submit']))
{
echo "Your First Name is: " . $_POST["fname"] . "<br>";
echo "Your Last Name is: " . $_POST["lname"] . "<br>";
echo "Your City is: " . $_POST["city"] . "<br>";
echo "Your State is: " . $_POST["state"] . "<br>";
echo "<br>";
echo "Your Message is: " . $_POST["message"];
}
?>
The PHP parses the HTML form data and uses the echo statement to display the results in the browser window.
If the GET method is used instead of the post method <form method="get" action="process.php">
, the $_POST array is replaced by the $_GET array. It is also possible to take advantage of the $_REQUEST array. The array can be used to collect data submitted through either the post or get method. The $_REQUEST variable can also be used with Cookies, which is covered in a later section.
At this point you may question whether it is better to use the get or post method with PHP form processing. Although both specify the manner in which form information is transmitted to the page identified in the action attribute, the POST method is recommended.
- GET - information from the form is appended to the action URL creating a query string. If the processing of a form has no lasting observable effect on the state of the world, then the form method should be GET. Many database searches have no visible side-effects and make ideal applications of query forms.
- POST - (Recommended) information from the form is transmitted as a separate data stream. If the service associated with the processing of a form has side effects (for example, modification of a database or subscription to a service), the method should be POST. The POST method does protect the integrity of the data since it cannot be viewed.
In the previous example, the form processing application consisted of two separate pages - an HTML form page (form_page.html) and a PHP page (process.php). The HTML page is static, containing only presentation details and no scripting. In contrast, the PHP page contains only a script to process the form data and no HTML tags or presentation details. It is a common practice with form processing in PHP to separate the presentation details from the scripting. With this method the PHP script page can be coded in such a way that it can be re-used with multiple HTML form pages. Reusability is a common practice in programming that enables code to the re-used in different programs, thus saving the cost of writing applications from scratch each time.
While separation of HTML markup and PHP code is a practice used by many developers, it is also possible to combine markup and PHP code into a single PHP file. This practice produces only a single file, simplifying the coding and error detection process. The following example shows the previous example (form_page.html and process.php) combined into a single PHP page - form_process.php.
form_process.php
<?php
echo "Your First Name is: " . $_REQUEST["fname"] . "<br>";
echo "Your Last Name is: " . $_REQUEST["lname"] . "<br>";
echo "Your City is: " . $_REQUEST["city"] . "<br>";
echo "Your State is: " . $_REQUEST["state"] . "<br>";
echo "<br>";
echo "Your Message is: " . $_REQUEST["message"] . "<br><br>";
?>
<!DOCTYPE html>
<html>
<head>
<title>A Web Page</title>
</head>
<body>
<form action="form_process.php" method="post">
<fieldset>
<table>
<tr>
<td>First Name: </td>
<td><input type="text" name="fname" value="John"></td>
</tr>
<tr>
<td>Last Name: </td>
<td><input type="text" name="lname" value="Smith"></td>
</tr>
<tr>
<td>City: </td>
<td><input type="text" name="city" value="Atlanta"></td>
</tr>
<tr>
<td>State: </td>
<td><input type="text" name="state" value="Georgia"></td>
</tr>
<tr>
<td>Message:</td>
<td><textarea name="message" cols="30" rows="5">I like PHP.</textarea></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="submit" value="Submit Data"></td>
</tr>
</table>
</fieldset>
</form>
</body>
</html>
The PHP code block is placed at the top of the page. Also, the form tag action is changed to "form_process.php". Now, the page will post to itself and not a separate PHP page. A final step is required in order for the new page to work properly. Take a look at the generated page output below:
Notice: Undefined index: fname in line 5
Your First Name is:
Notice: Undefined index: lname in line 6
Your Last Name is:
Notice: Undefined index: city in line 7
Your City is:
Notice: Undefined index: state in line 8
Your State is:
Notice: Undefined index: message in line 10
Your Message is:
First Name:
Last Name:
City:
State:
Message:
Here the HTML form section displays properly. However, PHP code block has been executed prior to form submission (or before the submit button is clicked). This causes the string values in the echo statements to be display when the page loads. The concatenated $_REQUEST[] values are missing because the form has not been submitted. The solution to this problem is to prevent any of the PHP code block from executing until the form is submitted or until the submit button is clicked. This is possible using an if statement. When the page loads, we can use an if statement to determine if the form is submitted by using isset function (e.g, isset($_REQUEST['submit']) or isset($_REQUEST'submit'] == true)). This statement is true only after a form submission has been triggered as a result of the submit button being clicked. The previous page is shown below using the if statement to check for form submission.
form_process.php
<?php
if (isset($_REQUEST["submit"]))
{
echo "Your First Name is: " . $_REQUEST["fname"] . "<br>";
echo "Your Last Name is: " . $_REQUEST["lname"] . "<br>";
echo "Your City is: " . $_REQUEST["city"] . "<br>";
echo "Your State is: " . $_REQUEST["state"] . "<br>";
echo "<br>";
echo "Your Message is: " . $_REQUEST["message"] . "<br><br>";
}
?>
<!DOCTYPE html>
<html>
<head>
<title>A Web Page</title>
</head>
<body>
<form action="form_process.php" method="post">
<fieldset>
<table>
<tr>
<td>First Name: </td>
<td><input type="text" name="fname" value="John"></td>
</tr>
<tr>
<td>Last Name: </td>
<td><input type="text" name="lname" value="Smith"></td>
</tr>
<tr>
<td>City: </td>
<td><input type="text" name="city" value="Atlanta"></td>
</tr>
<tr>
<td>State: </td>
<td><input type="text" name="state" value="Georgia"></td>
</tr>
<tr>
<td>Message:</td>
<td><textarea name="message" cols="30" rows="5">I like PHP.</textarea></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="submit" value="Submit data"></td>
</tr>
</table>
</fieldset>
</form>
</body>
</html>
Now the code in the PHP section of the page is only displayed after the condition (isset($_REQUEST['submit'])) validates to true meaning the submit button has been clicked and the form submission process has begun. For the most part, the practice of separating PHP and HTML or combining the two becomes a matter of preference.
The $_REQUEST Collection
The PHP $_REQUEST collection provides valuable assistance in gathering form information transmitted to the server by putting it into a structure for convenient script processing. The $_REQUEST collection intercepts the name/value string, parses the string into names and associated values, and places this information into an associative array, each indexed by its associated form field name. PHP also provides $_POST and $_GET collections, however the $_REQUEST collection is often a better choice, particularly in situations when data is submitted from a remote site and it is not known whether the post or get method is used.
$_REQUEST Collection
Names | Values |
fname -> | John |
lname -> | Smith |
city -> | Atlanta |
state -> | Georgia |
message -> | I like PHP. |
submit -> | Submit Data |
Once the data values are in the $_REQUEST Collection they can be easily referenced by their names using the syntax:
$_REQUEST["fname"] ="John";
$_REQUEST["lname"] = "Smith";
$_REQUEST["city"] = "Atlanta";
$_REQUEST["state"] = "Georgia";
$_REQUEST["message"] = "I like PHP.";
$_REQUEST["submit"] = "Submit Data";
The array index value corresponds to the value of the form control tag's name attribute. Thus, the reference $_REQUEST['fname'] points to the value entered into the First Name field; the reference $_REQUEST['lname'] points to the value entered into the Last Name field; ... and the reference $_REQUEST['submit'] is a reference to the value assigned to the Submit button. From a programming standpoint, $_REQUEST['name'] works like a program variable that references a value stored in that variable.
Iterating through the $_REQUEST Collection
Using a foreach loop we can iterate through the $_REQUEST Collection. It does provide a good way of debugging scripts that process form information. It also permits you to view the field names and submitted values to make sure that the correct information is being transmitted from the form.
<?php
foreach($_REQUEST as $key => $value)
{
echo $key;
echo ": " . $value;
echo "<br>";
}
?>
On each loop, the value of the current $_REQUEST element is assigned to the variable $value and the array pointer is advanced by one. The current array's index is assigned to the variable $key on each loop.
This script displays each of the field names (item) on the form along with its associated value with each pair listed on a separate line. Using the example values shown above, the output would appear as follows:
fname: John
lname: Smith
city: Atlanta
state: Georgia
message: I like PHP.
submit: Submit Data
From the output you can confirm that the expected data were transmitted properly to the form_process.php page prior to the actual processing of the form data.