Working with Forms

Session Checklist

✓ Understanding HTML forms

✓ Reviewing form fields

✓ Understanding how PHP handles form data

✓ Handling file uploads

©I TML forms provide an excellent framework for receiving data from users. They provide tJ a data entry GUI, rudimentary error checking, and can be used to pass the received I data on to a script where the data can be parsed, stored, and so on. 30 Min. This session reviews HTML forms and how PHP can be used as a form handler to receive To Go and use the data from the forms.

Understanding How HTML Forms Work

Before delving into how PHP works with forms, you should understand how HTML forms themselves work. HTML forms enable a Web developer to design a graphical environment for Web users to input data. This environment uses fields and controls similar to those used in application program dialog boxes.

Standard HTML Form Elements

As of this writing, standard HTML supports the following form elements:

• Text box — A single-line, free-form text field.

• Text area — A multiline, free-form text field.

• Password box — A single-line field like a text box, but any input in a password field shows up as asterisks (to help obscure sensitive data).

• Selection list — A multi-field text box that enables the user to select one or more of its entries.

• Check box — An option that the user can select (check) or deselect (uncheck).

• Radio button — Usually used in groups, radio buttons enable a user to select one of several options.

• Button — A standard button image displaying specific text.

• Hidden — A special field that stores data invisible to the user.

• Submit button — A special button that causes the form to be submitted.

• Reset button — A special button that causes the form to be reset to default field entries.

Certain browsers support supersets of these form elements. However, this book covers only the basic form elements in the HTML 4.0 standard. The file input type, which enables users to submit a file for uploading, has also been omitted. This field type is covered in the section "File Uploads," later in this session.

If you want more information on HTML and forms, pick up a copy of HTML 4.01 Weekend Crash Course, by Greg Perry (Wiley Publishing).

Listing 19-1 shows a sample of each of these fields in an HTML document. Figure 19-1 shows how this code looks in a browser.

Listing 19-1 sampform.html

First Name: <input type=text name=fname size=20><br>

Last Name: <input type=text name=lname size=20><p> <p>

<textarea name=addr cols=20 rows=4></textarea><p> <p>

Password: <input type=password name=pwd size=20><p> <p>

<!-- Select li What product(s interested in? <select name=p

<opt <opt <opt <opt <opt <opt on name on name on name on name on name on name st -- >

rod[] multiple size=4> =MB>Motherboards =CPU>Processors =Case>Cases =Power>Power Supplies =Mem>Memory =HD>Hard Drives =Periph>Peripherals

<option name

<!-- Check boxes --> How should we contact you?<br> <input type=checkbox name=email checked> Email<br>

<input type=checkbox name=postal> Postal Mail<br> <p>

How soon will you be buying hardware?<br>

<input type=radio name=buy value=ASAP>ASAP<br>

<input type=radio name=buy value=10>Within 10 business days<br>

<input type=radio name=buy value=30>Within the month<br>

<input type=radio name=buy value=Never>Never!<br>

<input type=submit>&nbsp;&nbsp;&nbsp;<input type=reset> <p>

<input type=button name=Leave value="Leave!"> <p>

<input type=image name=Coupon src="coupon.jpg"> <!-- Hidden field -->

<input type=hidden name=referredby value=Google>

</td></tr> </table> </form> </body> </html>

Radio buttons Text area

Check boxes Submit button

Reset button

Radio buttons Text area

Check boxes Submit button

Reset button

Post Two Submit Buttons

Button Image

Figure 19-1 Browser output of sampform.html

Button Image

Figure 19-1 Browser output of sampform.html

Notice that each form field tag includes a name parameter. Scripts and form handlers use this parameter to uniquely identify each field.

Form Actions

When a user clicks the Submit button, the browser passes the data to the defined "action" in the form tag. For simplicity's sake, Listing 19-1 didn't contain several elements of the form tag. Although this code enables a form to be displayed, the form isn't very useful because it has no method to pass the input data along to an appropriate handler— making the data rather useless.

The full syntax of the form tag is as follows:

<form name=name action=ur7 method=get/post >

The name parameter is helpful for identifying the form, especially when your document has several forms. The action parameter is a URL to a form handler. The form handler is typically a CGI program or other script that interprets the data and does something useful with it. The method parameter specifies how the data should be passed to the handler. The valid options for method are get and post.

The get method appends the data to the URL as name/value pairs using the following format:

http://url?name1=value1&name2=value2&...

The name/value pairs are separated from the URL with a question mark (?), and each pair is separated from the previous set by an ampersand (&).

The post method encodes the data into a separate part of the HTTP request that is passed to the handler.

Of the two, post is usually the preferred method because it is noticeably cleaner (it doesn't clutter the URL), it can hold more data, and its data handling is more robust (no messy quoting). However, not every handler can accept post data and sometimes using get is simply more convenient.

How Form Data Is Returned

The last step in this HTML form primer describes how form data is returned from a form to the handler. Table 19-1 describes the various form elements and the data they return. 20 Mm. J

Table 19-1 Returned Form Element Data

Element

Data Returned

Text box

The data entered into the text box.

Text area

The data entered into the text area.

Password box

The data entered into the Password box (real data, not asterisks).

Select list

A single value or an array if multiple parameters are used (but

notice that an option's name is used instead of its text if the name

parameter is used).

Check boxes

If checked, the contents of the field's value parameter are

returned (or a generic "on", if no value was given). If the box is

not checked, nothing is returned.

Radio buttons

The value or name (if no value was given) of the selected button.

Hidden

The value of the field.

Buttons and images do not return values; they must be used with scripting within the HTML document to perform actions. This would be done using a scripting language such as JavaScript. Exceptions are the Submit and Reset buttons. The Submit button causes the action of the form to take place, while the Reset button reloads the form in its default state. Both of these buttons can also be scripted — inside the HTML document — to circumvent their default behavior.

O Hidden fields make convenient places to store various state data — data that helps to control scripts but which the user shouldn't see. We use this technique in later sessions. However, be careful when using hidden fields for sensitive data — remember that users can see the field definition if they choose to view your form's source.

PHP Form Data Handling

What does all this mean to PHP? If you can figure out how to get at and use the information passed from forms, you have a powerful form-handling platform at your disposal. This platform also integrates with almost every known Web and system technology, making it easy to store, retrieve, and work with form data.

Parsing $_POST

You might have noticed that the output of the phpinfo() function includes post data values in its output. Using a script with the phpinfo() function facilitates tracking form data. The data can be found in the "PHP Variables" section of the phpinfo() output under the values of $_POST or $_GET, depending on the method your form uses.

For example, this minimal script works nicely:

phpinfo();

Store this code in a file named handler.php and change the form tag in the preceding example to the following:

form action=handler.php method=post>

Filling out the form shown in Figure 19-1 and clicking the Submit button results in the information shown in Figure 19-2.

You may have noticed the brackets after the select tag's name in the example form:

<select name=prod[] multiple size=4>

These brackets force the handler to treat the value returned by the field as an array — as several values may be returned (due to the multiple parameter). However, you might also have noticed that the returned values are duplicated inside the array when PHP parses them.

The data in the prod field illuminates a bug between PHP 4.2+ and Apache 2.0+ — namely, the duplication of array elements. (Processors and Cases are duplicated in the prod array.) At the time of this writing, only one easy fix was available: using the array_unique() function to remove duplicates from the array prior to processing it. (of course, this doesn't work if the array is supposed to have duplicates.) This is a known bug that one hopes will be fixed in short order.

Q i Mnt kCiffia

E* E« fit

Boo

iHWtt IMIi !«• tJMF

s»<

(MM

| —- -1—! —

- l/Ji]

/KM H* ht /HllHilMWIlt JS»» JB«|(H JrilW(

('HI' Vvttblti

Varufcta

M.W

WIH

pwiii™-)

Vrtt

„»an ur|

ID mu, a

.PMII

——■

An*

1*1 *h

t

.(mil—n

&

POJII w, 1

10

.

jwnnftinwi

tifH* U

. itfm^ wr TP .m 17

KM

llRMIBCltriP win Mwn

|MW»{MI,U.I»*i«K.*4».>*tA.l]MMnnaB

1LLL1-J

- [ii"

ri £ m 0"

KIW

m Df

<"« 1 • I Itcsi

Figure 19-2 Information from the handler on the post information it received.

Notice that all of the data is stored in a $_POST variable. This variable is one of many superglobal variables built into PHP. Superglobal variables are used by PHP to store various pieces of environmental, system, and Web-related data. (Review the "PHP Variables" section of phpinfo() for more superglobals.)

Now that you know where the data is stored, how do you use it?

The $_POST variable is actually a keyed array — the keys are the names of the form data fields and their values are the data returned from each field. In the preceding example, $_POST['fname'] would store Steve.

To get at each key/value pair, you could use a foreach() loop such as the following:

This loop parses the $_POST variable into its respective keys and variables. Each iteration of the loop parses a new set of key/value pairs. Therefore, you want to change the handler.php script to the following:

// Generic form data parser

// Begin HTML page and field table print <<<HTML

<table cellpadding=20 border=1> <tr><td><b>Name</b></td>

<td><b>Value</b></td></tr> HTML;

// For each POST field foreach ($_POST as $key => $value) { // Print the key in the first column print "<tr><td>$key&nbsp;</td>"; print "<td>";

// If the field is an array, parse it if (is_array($value)) { foreach ($value as $selkey => $selvalue) { print "$selkey : $selvalue&nbsp;<br>";

// Else (not array) just print value in // second column print "$value&nbsp;";

// Close open HTML elements print <<<HTML

Notice the nested foreach() loop within the main loop. Because <select> fields are returned in arrays, you need to identify any field that is an array and parse it to get all values. Figure 19-3 shows the results of the sample data run through the new handler.

This handler is a good troubleshooting tool for forms, as is the phpinfo() version. Consider keeping them both handy to help solve problems with your form data.

Auto-Register Globals: Easier, But Less Secure

An easier way for PHP to handle form data is by using the auto-register-globals functionality of the language. The php.ini file includes a setting, register_globals, that automatically registers select pieces of data as global variables. One of those pieces of data is form POST data. For example, say you have the following field in a form:

<input type=text name=fname size=20>

It

S» BMMMU Iwtl !«• Hff

Met

'^HMH iJWcn

W»H ^RtHHtl />>■ HM

JSwW jSMP JT,im(

Namp

YUM

Ijwmt

Sine

biantt

Schafer

Mir

123 Main SI Armrtiej* USA

pud

li^WflUnK

2FtWWSort

«. a us

moiMm Dm i M tfcii

Figure 19-3 The new handler output

If you use a PHP script as the form handler, the variable $fname is automatically created and holds the value of the field when the form was submitted. You could then dispense with the parsing of $_POST and reference the field values directly ($fname, $lname, $pwd, and so on).

As of PHP version 4.2.0, the default for this setting is Off. The reasoning behind disabling such a useful feature has to do with security. With register_globals set to On, variables can be initialized from the URL. For example, the following URL would result in the variable $authorized being set equal to 1 in the script sample.php:

http://<server>/sample.php?authorized=1

If the code within sample.php were poorly written and the variable $authorized was used to actually authorize a user, the preceding URL could be used to gain unauthorized access. Therefore, the PHP community prefers that register_globals remains Off and that PHP coders use the superglobal variables to parse data passed to their scripts.

Working with File Uploads

Sometimes it is useful to allow users to post an actual file as data in a form. For example, you could allow prospective employees to post their resume to your company's employment site when filling out an application for a position.

The file type of the input tag has the following syntax:

<input type=file accept=<mime_type(s)> name=<field_name> value=<default_filename>

When placed in a form, this tag generates a text box with a Browse button.

The user can either type a file name into the text box (including a full path to a local file) or use the Browse button to spawn a File Manager window to navigate to the file. When the form is submitted, the file is sent to the handler using the HTTP POST protocol. Notice that the file_uploads setting in the php.ini file must be On for PHP to receive HTTP uploads.

PHP has a special superglobal variable to handle posted files — namely, $_FILES. Table 19-2 describes the $_FILES variable's various components.

Table 19-2 $_FILES Components

Component (key)

Use

name

The name of the uploaded file (what the user entered, minus the

path information).

type

The MIME type of the uploaded file.

tmp_name

The temporary name of the uploaded file. (See the explanation of

temporary names in the text that follows.)

error

Error code corresponding to the upload error. Error code zero (0)

equals no errors.

size

Size of the file, in bytes.

The $_FILES superglobal is usually stored as a two-dimensional array. The first dimension is the filename and the second is the keys and/or values listed in Table 19-2. For example, an input file tag with the name resume has its temporary name stored in $_FILES['resume']['tmp_name'].

The PHP handler script receives the file and stores it in the directory specified by the upload_tmp_dir setting in the php.ini file. The file is given a temporary, unique name. It is the script's responsibility to do something useful with the file — move it to another directory, parse it for information, and so on.

You can control how much information can be uploaded in several ways. The upload_max_filesize setting in the php.ini file has a default of 2MB. Any file over that limit causes an error. You can also place a special hidden tag before the input file tag in your HTML document, such as the following:

<input type=hidden name=MAX_FILE_SIZE value=bytes>

This tag controls how much data the form actually passes on. Notice that unscrupulous users can view this code, save it to another file, edit it to their liking, and circumvent the limit. It's best to always have the upload_max_filesize setting set to a reasonable limit (in the php.ini file or via the ini_set() function).

Now you can put this together into a working example. Start with a basic upload form:

<!-- Form needs to be multipart for file upload--> <form action="filehandler.php" method="post" enctype="multipart/form-data">

Enter file name (include full path)<br> or use the browse button:<p>

<input type=hidden name=MAX_FILE_SIZE value=100000>

<input type=file name=resume> <p>

<input type=submit value=Upload>

Notice that the form needs to be specified as encoded multipart form data (enctype="multipart/form-data"). This parameter tells the handler to expect multiple parts to the submission of the form data — one of those parts is the file upload. Then create a simple file handler (filehandler.php) to deal with the upload:

HTML;

// Get the data out of the "resume" form element $filedata = $_FILES['resume']; $tempfile = $filedata['tmp_name'];

// Check to see if the file is indeed an upload if (is_uploaded_file($tempfile)) { // Create destination path/filename (Linux format) $destfile = "/var/www/html/".$filedata['name'];

// Attempt file move and report success/failure if (move_uploaded_file($tempfile, $destfile)) {

print "File moved to: $destfile"; } else {

print "File cannot be moved to: $destfile";

// File specified in "resume" element was // not an upload, or nothing specified print "No uploaded file!";

// Close open HTML elements print <<<HTML

HTML;

Notice the following about the preceding example and file uploads in general:

• Always move the temporary file to a more permanent location before performing any other actions on it.

• The temporary file is deleted at the end of the handling script.

• The move_uploaded_file function replaces the destination if it exists.

• Always check the file specified with the is_uploaded_file function. Otherwise, your code might end up working with hazardous files.

• The code checks each step of the operation and responds or reports accordingly. If the file upload or move fails, the $_FILES superglobal can be further parsed for useful information to report to the system administrator or the user (for example, File was too big. Uploads have a 100K limit. )

• You probably do not want to store files using the file name included with the file. For example, what happens when a user on one platform uploads an invalid file name for your server platform? At least consider checking the file name before relying upon it.

• You can further control the type of data allowed as an upload with the accept parameter of the input file tag. This parameter accepts a comma-delimited list of MIME types that are valid uploads. If the file specified is not one of those types, the upload fails. (Notice that the MIME type doesn't fully guarantee that the data in the file matches the type.)

• Remember that the user ID under which the PHP process is running needs to have appropriate rights to the temporary directory and the destination directory in order for the upload and move to succeed.

Review

This session reviewed HTML forms and showed you how to use PHP as a form handler. The Done! techniques learned in this session are useful in later sessions and projects — where you use forms to gather information from users as well as to display data from MySQL for editing.

_Quiz Yourself_

1. Why does the password form field print asterisks as data is entered? (See "Standard HTML Form Elements.")

2. Why should you always use name parameters in form field tags? (See "Standard HTML Form Elements.")

3. How do forms, using the GET method, pass information to their handler? (See "Form Actions.")

4. What type of variable is $_POST? (See "Parsing $_POST.")

5. What is the compelling argument against using register_globals? (See "Auto-Register Globals: Easier, But Less Secure.")

6. Why shouldn't you always store an uploaded file using the name provided by the user? (See "Working with File Uploads.")

Was this article helpful?

+1 0

Post a comment