Using HTML forms with PHP

Access single and multiple form values

One of the advantages of PHP has always been the ability to easily manipulate information submitted by the user through an HTML form. In fact, PHP version 4.1 adds several new ways to access this information and effectively removes the one most commonly used in previous versions. This article looks at different ways to use the information submitted on an HTML form, in both older and more recent versions of PHP. It starts out by looking at individual values and builds to a page that can generically access any available form values.

Nicholas Chase (nicholas@nicholaschase.com), President, Chase and Chase, Inc.

Nicholas Chase has been involved in Web site development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. Nick has been a high school physics teacher, a low-level radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, and an Oracle instructor. More recently, he was the Chief Technology Officer of Site Dynamics Interactive Communications in Clearwater, Florida, and is the author of three books on Web development, including Java and XML From Scratch (Que). He loves to hear from readers and can be reached at nicholas@nicholaschase.com.



01 August 2002

Note: This article assumes that you have access to a Web server running PHP version 3.0 or above. You'll need a basic understanding of PHP itself, and of creating an HTML form.

The HTML form

During the course of the article, you'll look at how different types of HTML form elements provide information that PHP can access. For this example, I use a simple information form that consists of two text fields, two checkboxes, and a select box that permits multiple entries:

Listing 1. The HTML form
<html>
<head><title>Tour Information</title></head>
<body>

<h2>Mission Information</h2>

<form action="formaction.php">
  <table width="100%">
    <tr><td>Ship Name:</td><td><input type="text" name="ship" /></td></tr>
    <tr><td>Trip Date:</td><td><input type="text" name="tripdate" /></td></tr>
    <tr><td colspan="2">Mission Goals:</td></tr>
    <tr>
      <td><input type="checkbox" name="exploration" value="yes" />
               Exploration</td>
      <td><input type="checkbox" name="contact" value="yes" />
               Contact</td>
    </tr>
    <tr>
      <td valign="top">Crew species:  </td>
      <td>
        <select name="crew" multiple="multiple">
           <option value="xebrax">Xebrax</option>
           <option value="snertal">Snertal</option>
           <option value="gosny">Gosny</option>
        </select>
      </td>
    </tr>
    <tr><td colspan="2" align="center"><input type="submit" /></td></tr>
  </table>
</form>

</body>
</html>

Without a method specified, this form uses the default, GET, in which the browser appends form values to the URL, as in:

http://www.vanguardreport.com/formaction.php?
ship=Midnight+Runner&tripdate=12-15-2433&exploration=yes&crew=snertal&crew=gosny

Figure 1 shows the form itself.

Figure 1. The HTML form
The HTML form

The old way: Accessing global variables

The code shown in Listing 2 treats the forms values as globals:

Listing 2. Form values as globals
<?php

echo "Ship = ".$ship;
echo "<br />";
echo "Tripdate = ".$tripdate;
echo "<br />";
echo "Exploration = ".$exploration;
echo "<br />";
echo "Contact = ".$contact;

?>

The resulting Web page shows the submitted values:

Ship = Midnight Runner
Tripdate = 12-15-2433
Exploration = yes
Contact =

(As you'll see in a minute, there's no value for Contact because that box wasn't checked.)

The notation in Listing 2 is certainly convenient, but it is only available if the PHP directive register_globals is set to on. Prior to version 4.2, this was the default, and many PHP developers may even be unaware that there's an issue. Starting with version 4.2, however, the default setting for register_globals is off, in which case this notation doesn't work because the variables are never created and initialized with the appropriate values.

You can, however, use other ways to initialize these variables. The first is to change the value of register_globals. Many developers who work on shared servers don't have the option to change this value for the entire server, but behavior can be changed for a particular site. If you have access to the .htaccess file, you can turn on register_globals by adding the directive:

php_flag register_globals on

Because of the uncertainty in whether this feature is available, developers are advised that it's better not to use or rely on this method of acquiring variables. So what options do you have?

If your system is running version 4.1 or higher, another option is to selectively register sets of globals using import_request_variables(). You can use this function to import get, post, and cookie values, and to add a prefix to each, if desired. For example:

<?php

import_request_variables(gp, "formval_");

echo "Ship = ".$formval_ship;
echo "<br />";
echo "Tripdate = ".$formval_tripdate;
echo "<br />";
echo "Exploration = ".$formval_exploration;
echo "<br />";
echo "Contact = ".$formval_contact;

?>

Here, both get and post values are imported -- use c to import cookie values -- and because p follows g, post values will override get values of the same name.

But what if, like many developers, you're not running version 4.1 or higher?


Accessing form value collections

For those who are running older systems or want to get away from globals altogether, you have the option to use the $HTTP_GET_VARS and $HTTP_POST_VARS arrays. These collections are deprecated, but they are still available, and still in wide use. When they do go away, they'll be replaced by the $_GET and $_POST arrays, added in version 4.1.

Both of these arrays are of a type known as hash tables. A hash table is an array that is indexed by string values rather than integers. In the case of forms, the values are accessible by their name, as shown in Listing 3:

Listing 3. Accessing form values through hash tables
<?

$ship_value = $HTTP_GET_VARS['ship'];
echo $ship_value;
echo "<br />";

$tripdate_value = $HTTP_GET_VARS['tripdate'];
echo $tripdate_value;
echo "<br />";

$exploration_value= $HTTP_GET_VARS['exploration']; 
echo $exploration_value;
echo "<br />";

$contact_value = $HTTP_GET_VARS['contact'];
echo $contact_value;
?>

You can use this method to retrieve values for each of your fields by name.


One name, multiple values

So far, each name has corresponded to only one value. What happens when there's more than one value? The crew species list box, for example, allows multiple values to be submitted with the name crew.

Ideally, you'd like these values to be available as an array so you can retrieve them explicitly. To make that happen, you've got to make a slight change to the HTML page. Fields that are to be submitted as arrays should be named with brackets, as in crew[]:

Listing 4. Modifying the HTML page
...
       <td>
           <select name="crew[]" multiple="multiple">
                   <option value="xebrax">Xebrax</option>
                   <option value="snertal">Snertal</option>
                   <option value="gosny">Gosny</option>
           </select>
       </td>
...

Once you've made this change, retrieving the form value actually yields an array:

Listing 5. Accessing the variables as an array
...
$crew_values = $HTTP_GET_VARS['crew']; 
echo "0) ".$crew_values[0];
echo "<br />";
echo "1) ".$crew_values[1];
echo "<br />";
echo "2) ".$crew_values[2];
...

Submitting the page now shows the multiple values:

0) snertal
1) gosny
2)

Notice first that this is a zero-based array. The first value encountered is in position 0, the next in position 1, and so on. In this case, I submitted only two values, so the third spot is blank.

Normally, you don't know how many items will be submitted, so instead of calling each item directly you can use the fact that it's an array to your advantage, using the sizeof() function to determine how many values were submitted:

Listing 6. Determining the size of the array
...
for ($i = 0; $i < sizeof($crew_values); $i++) {
    echo $crew_values[$i];
    echo "<br />";
}
...

Sometimes, however, the problem is not too many values, but no values at all.


The amazing disappearing checkboxes

It's important to realize that a checkbox is only submitted if it's actually checked. Otherwise, its very absence tells you what you need to know: the user didn't click this checkbox. In the case of checkboxes, you can check explicitly to see whether the value was set using the isset() function:

Listing 7. Checking to see if a checkbox was submitted
...
$contact_value = $HTTP_GET_VARS['contact']; 
echo $contact_value;

if (isset($contact_value)) {
  //The checkbox was clicked
} else {
  //The checkbox wasn't clicked
}
...

Getting all form values

Checkbox fields are just one example of a situation where you may not be entirely certain of the names of form values to expect. Often, you might find it useful to have a single routine that look at all of your form values in a generic way.

Fortunately, because $HTTP_GET_VARS and its ilk are simply hash tables, you can use some of the properties of arrays to manipulate them. For example, you can use the array_keys() function to get a list of all of the potential value names:

Listing 8. Getting a list of form value names
...
$form_fields = array_keys($HTTP_GET_VARS);
for ($i = 0; $i < sizeof($form_fields); $i++) {

    $thisField = $form_fields[$i];
    $thisValue = $HTTP_GET_VARS[$thisField];
    echo $thisField ." = ". $thisValue;
    echo "<br />";  

}
...

In this case, you actually combine several techniques. First, retrieve an array of form field names and call it $form_fields. The $form_fields array is just a typical array, so you can use the sizeof() function to determine the number of potential keys, and loop through each one. For each one, you retrieve the name of the field and then use that name to get the actual value. The result is a Web page that reads:

ship = Midnight Runner
tripdate = 12-15-2433
exploration = yes
crew = Array

Notice two important things here. First, the contact field didn't return at all, as expected. Second, the crew value (which is, incidentally, named crew and not crew[], as you might expect) is an array, and not a value. To actually retrieve all values, you'll need to detect any arrays using the is_array() function and handle them accordingly:

Listing 9. Accounting for arrays
...
for ($i = 0; $i < sizeof($form_fields); $i++) {

    $thisField = $form_fields[$i];
    $thisValue = $HTTP_GET_VARS[$thisField];
    if (is_array($thisValue)){
        for ($j = 0; $j < sizeof($thisValue); $j++) {
            echo $thisField ." = ". $thisValue[$j];
            echo "<br />";
        }
    } else {
        echo $thisField ." = ". $thisValue;
    }
    echo "<br />";  

}
...

The result is all of the data that was actually submitted:

ship = Midnight Runner
tripdate = 12-15-2433
exploration = yes
crew = snertal
crew = gosny

One final note: dots

Now that you have a form action page that will adapt to whatever form values you throw at it, you need to take a moment to look at one situation that often catches PHP programmers by surprise.

In some cases, rather than using a submit button, a designer opts for a graphic button, as shown in Figure 2 and the code shown in Listing 10.

Listing 10. Adding an image button
...
        <tr>
           <td valign="top">Crew species:  </td>
           <td>
               <select name="crew[]" multiple="multiple">
                   <option value="xebrax">Xebrax</option>
                   <option value="snertal">Snertal</option>
                   <option value="gosny">Gosny</option>
               </select>
           </td>
        </tr>
        <tr>
           <td colspan="2" align="center">
              <input type="image" src="button.gif" name="formbutton"/>
           </td>
        </tr>
    </table>
...
Figure 2. Graphic button on form
Adding a graphic button

Notice that although there's only one image, there are two buttons, or desired outcomes, in the graphic. As a developer, you can tell where the user clicked by examining the x and y coordinates that are returned with the values. In fact, submitting the form as is might create a URL and querystring ending in:

...snertal&crew%5B%5D=gosny&formbutton.x=37&formbutton.y=14

Notice the .x and .y appended to the name of the button. If you were to submit the page and look at the results, however, you'd see:

ship = Midnight Runner
tripdate = 12-15-2433
exploration = yes
crew = snertal
crew = gosny

formbutton_x = 37
formbutton_y = 14

Notice that the period (.) has been converted to an underscore (_). This may seem a little odd, but it's necessary because variable names in PHP can't have periods in them, so $formbutton.x would be an illegal variable name. In fact, any periods in form names -- not just those for image buttons -- are converted to underscores.


Summary

In this article, you looked at some of the ways to access information submitted by a user through an HTML or XHTML form. How you handle this information will depend on the version of PHP you're using and whether you can access your form variables as globals. In any case, form values are available as arrays, and you can use the properties of arrays to loop through any available values.

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Web development on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, Linux
ArticleID=11232
ArticleTitle=Using HTML forms with PHP
publish-date=08012002