Php Forms
— print (last updated: Feb 18, 2009) print

Select font size:
Download the PhpForms.zip archive. Install it into your default website folder and set it up as a NetBeans project as done in Php Basics.

Web-based applications

Php has the ability to create a dynamic web page by obtaining non-static information, say from a database, and presenting this to the user. The user then interacts with this program-generated web page and further dynamic web pages are created. The user interacts with a web page presenting HTML form elements and/or hyperlinks. After making choices and/or clicking some element (like a button), data is submitted to another program (possibly the same one which generated the original form) which then generates the next web page, and so on.

Web-based applications have a very different style than, say, Java Swing-based GUI applications. They are event-driven, as indicated, but not thought of as a single program, rather a series of programs which start and terminate for each page generated. Even though it's not technically correct, the term stateless applies to web applications due to the fact that they are not a single program running.

The other major difference with web applications is that the activations normally are stacked. This is what the "Back" button in the browser is all about: keeping of a history with the ability to go back to previous activations. This feature has both good points and bad points. Say, for example, a web activation represents a "one-time" transaction, like deleting a database record. The notion of going back to that activation is error-prone at best. One of the features of AJAX-based web applications is the ability to make efficient server-side executions which browser refreshing, and thus avoid stacking. Such a style makes a Web application appear more like other non web-based GUI applications.

Hyperlink activations

The default hyperlink activation is based on HTML code which looks like this:
<a href="some-url">some description</a> 
Hyperlink activations can be made to do other actions by replacing the URL by a JavaScript call:
<a href="javascript:javascript-code">.....</a> 
The above hyperlink activation of "some-url" is equivalent to this usage with the JavaScript location object:
<a href="javascript:location='some-url'">some description</a> 
There's no point in using this more complicated version, but the following related operation avoids stacking:
<a href="javascript:location.replace('some-url')">some description</a> 
For example, compare the effects of these two hyperlinks:
href="http://www.cs.wcupa.edu/rkline/csc417"
href="javascript:location.replace('http://www.cs.wcupa.edu/rkline/csc417')"

Query data processing

User-generated web data is transmitted as a list of parameters and values in a data string constructed like this:
name1=value1&name2=value2&...
where name1, name2, etc., typically correspond to the names given to the form elements and the values are (typically) those generated by the user by text entry or selection from various choices. It is possible for a parameter name to appear more than once, in which case it is called multi-valued, otherwise, it is single-valued.

GET/POST queries

A GET request to a server-side script is one which sends this parameter data string attached to the script's URL in the form of a query string following a ? after the script name:
http://.../SCRIPT?name1=value1&name2=value2&...
A POST request is one which sends this parameter string to the script through standard input

When to use GET vs. POST

There are reasons for choosing to use GET or POST queries: GET method is the method used by standard hyperlink activations. GET method is the default used by an HTML form (see below). Nevetheless, web-based applications generally prefer POST for form data transmission. Keep in mind that a GET query is "visible" and "repeatable" because the query is stored in the URL. Thus:

Processing parameters

In Php, parameter name/value pairs are processed and made available via these two (associative) arrays:
$_GET   and   $_POST
$_GET['name'] holds the value(s) of parameter name obtained from the query string. For $_POST['name'], the data is obtained from standard input. In many situations we do not need to differentiate the behavior of GET and POST requests and so it behooves us to merge these two arrays into a single one:
$param = array_merge( $_GET, $_POST );
and treat parameter values like this:
$param['name']
A multivalued parameter for Php must appear in the data string as follows:
name[]=value
i.e., the parameter name must use brackets suffix. In this case Php will treat $param['name'] as an array (or undefined). If we were to omit the brackets, $param['name'] is a scalar holding the last value set.

If no values are set for a parameter name (multivalued or not), $param['name'] is unset (null, undefined). The undefined usually doesn't cause problems for a single-valued parameter, but it will cause problems for a multivalued parameter regarded as an array. In practice, $param['name'] must be tested by the isset operation before being used as an array.

The script show-params.php illustrates how parameters passed to a Php script, say, through the query string, are accessed. Follow the instructions in the script itself to add by hand various query strings and see the results.

show-params.php
<? $param = array_merge( $_GET, $_POST ); $file = basename($_SERVER['PHP_SELF']); $title = "Show Parameter Values ($file)"; ?> <html> <head><title><?= $title ?></title></head> <body> <h2><?= $title ?></h2> In the browser location field, tack on a query string with parameter/value pairs like these: <pre> ?a=1 ?a=1&b=2 ?a=1&a=2 ?a[]=1 ?a[]=1&a[]=2 </pre> and view the results below. <hr /> <h4>number of parameters: <?= count($param) ?></h4> <h4>values</h4> <? foreach( $param as $param => $value ) { if (!is_array($value)) echo "$param => $value", "<br />"; else echo "$param => array(" , join(",", $value) , ")<br />"; } ?> </body> </html>

The web server environment

The web server environment in Php is represented by the special (associative) array $_SERVER which can assess other dynamic information about the script's activation: Here are some examples: A simple program which prints out the $_SERVER array is this:

print-environment.php
<pre style="font-size:10pt"> <? print_r($_SERVER) ?> </pre>

HTML Forms

An HTML form is enclosed within the tags:

<form action="PROGRAM" method="METHOD" target="TARGET">

  <!-- form elements -->

</form>
where

Form Components

The HTML form components provide the user interface. They consist of The elements use attributes specific to the element to change the appearance or behavior. Certain attributes, called boolean attributes, have no value and are activated simply be being present. For example, any form element can be disabled by using the boolean attribute
disabled
Using the disabled attribute typically "grays out" the element and makes it unusable, with the content still visible.

JavaScript attributes

These mouse and keyboard JavaScript event attributes take JavaScript code as their values. They can be used to modify the form-handling behavior, for example, by calling the JavaScript "submit()" value:
onclickmouse clicked in element
ondblclick mouse double-clicked in element
onmousedown/onmouseup mouse pressed/released in element
onmouseover mouse over element
onmouseout mouse not over element
onmousemove mouse position changed within element
onkeydown/onkeyupa key was pressed/released
onkeypress a key was pressed, then released
onfocus/onblur element acquires/loses focus by mouse click or tabbing
onselect text selected in a textfield or textarea
onchange value has been modified (for input, select, textarea )

Text Elements, Buttons, Hidden inputs

Text elements different from other form components in that the user determines the value associated with a parameter name. The HTML input element is used to create a variety of different components including textfields, buttons, hidden inputs, checkboxes, radio buttons, etc. The input element has the form:
<input type="TYPE" name="NAME" value="VALUE" ... />
where the NAME identifies the parameter name passed to the action script. These are the TYPE values of interest at this point: The HTML textarea element is used to create mutiline text entry elements. It has the form:
<textarea name="NAME" rows="ROWS" cols="COLS" ... >...</textarea>
where the NAME identifies the parameter name passed to the action script.

These are also used to control behavior ot textfields and textareas:

Effect of magic quotes

When Php uses magic quotes it automatically escapes all the quotes in anticipation of using this input as a value in an SQL query. Do not use them! You can do this by hand easily using the addslashes function or by inserting the values into a prepared statement.

By executing the following script, you can determine whether your installation of Php is using magic quotes or not.

test-magic-quotes.php
<h2>Magic Quote Test</h2> <h3>Server: <?= $_SERVER['SERVER_NAME'] ?></h3> <form> <input type="text" name="sample" readonly value="a'b&quot;c" /> <input type="submit" value="Press me to see if quotes are escaped" /> </form> <p> <?php if (isset($_GET['sample'])) { echo "output: ", $_GET['sample'], " (if the quotes are escaped, then magic quotes are on)" ; } ?> </p>
If magic quotes is on, you will see this output:
a\'b\"c
If you want to convince yourself that this really happens, edit your php.ini file, look for the line
magic_quotes_gpc = Off
change the Off to On and then restart apache. Make sure to then get rid of magic quotes, repeat the same sequence, except change the On to Off.

Displaying User Input

When you want to display user-generated input in a target script, you have to deal with the fact that this input may contain certain HTML-special characters, in particular these: "<", "&", """, ">". There are are possiblities: For most part we want the latter choice, and towards this end we use the Php function:
htmlspecialchars
to translate into HTML-special sequences. For inserting text into a textfield, you typically generate Php code that looks like this:
$escaped_text = htmlspecialchars($raw_text);
<input type="text" name="NAME" value="<?= $escaped_text ?>"/>
Single quotes are aren't escaped by htmlspecialchars and so you should avoid using them around a Php-generated value.

Form activation, button handling, hidden inputs

A form need not be activated by the pressing of a button. But if it is, the easiest way to know that the form was activated is to see a non-null value of a named button.

A hidden input name/value combination is one that doesn't show in any explicit way. These often offer a way of maintaining the "state" by passing a value from one form to another.

Sample form and handler

The HTML file text.html is a form with basic text components which also illustrates other features such as buttons and hidden parameters. The handler is the script text-handler.php as invoked by the attribute
action="text-handler.php"
within the form tag. This example illustrates a relatively easy separation of view from controller: text.html belongs to the view, written here exclusively in HTML; text-handler.php belongs to the controller and is written exclusively in Php. When you run the script:

text.php
<? $file = basename($_SERVER['PHP_SELF']); $title = "Text with external handler ($file)"; ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title><?= $title ?></title> <link rel="stylesheet" type="text/css" href="entry.css" /> </head> <body> <h2><?= $title ?></h2> <blockquote class="feedback"> Try these "torture" values using both submit buttons:<br /> <tt>tf: a&lt;b&gt;c"d<br /> ta: a&lt;/textarea&gt;b</tt> </blockquote> <form action="text-handler.php"> <table class="entry"> <tr> <td class="left">text field (<b>tf</b>):</td> <td><input type="text" class="text" name="tf"/></td> </tr> <tr valign="top"> <td class="left">text area (<b>ta</b>):</td> <td> <!-- no whitespace between start & end tags --> <textarea name="ta" rows="10"></textarea> </td> </tr> </table> <input type="hidden" name="h_input" value="783" /> <input type="submit" name="raw_button" value="Raw Input Button"/> <input type="submit" name="esc_button" value="Escaped Input Button"/> </form> </body> </html>

text-handler.php
<? $param = array_merge( $_GET, $_POST ); $tf = $param["tf"]; $ta = $param["ta"]; $raw_button = $param["raw_button"]; $esc_button = $param["esc_button"]; $h_input = $param["h_input"]; $title = basename($_SERVER['PHP_SELF']); if (isset($raw_button)) { $title .= " (raw input inserted)"; } elseif (isset($esc_button)) { $title .= " (escaped input inserted)"; $tf = htmlspecialchars($tf); $ta = htmlspecialchars($ta); } echo <<<END <h2>$title</h2> tf: $tf<br /><br /> tf value reinserted in a textfield: <input type="text" value="$tf" /> <br /><br /> ta: $ta<br /><br /> ta value reinserted in a textarea: <textarea>$ta</textarea><br /> <br /><br /> h_input: $h_input END;

Selection Elements

Selection elements are those where we are presented with a limited number of choices from which we can choose one or more values. The HTML elements which provide these choices are checkboxes, radio buttons and selection lists. In most situation we have control over the values generated by these elements which stands in contrast to the text elements.

Radio/Checkbox Elements

These types of elements are often used in groups in which the elements have the same name. The effect on checkboxes is to create multi-valued parameter data, whereas with radio buttons the data is single-valued because radio button group selection is mutually exclusive.

The HTML input element is also used to create checkboxes and radio buttons. We use:
<input type="TYPE" name="NAME" value="VALUE" ... /> label
where: The boolean attribute checked causes this element to be pre-selected (a radio group can, of course, have only one pre-selected value). In each case, the value "on" is assigned if there is no value specified.

Selection Lists

The HTML select and option elements are used to create selection lists. The format is like this:
<select name="NAME" ... >
<option value="VALUE">label</option>
...
</select>
Additional attributes for select include these: The option element permits the boolean attribute selected which sets that option to be pre-selected.

Single Selection Elements

From a form handler's point-of-view, parameter which are single-valued can be treated in pretty much the same way. In this respect we identify the two elements as being single-selection elements: A second distinction among these single-selection elements is this: In the former cases, you can never be in the state where nothing is choses, whereas, in the latter case there is initially no choice made, but once a choice is made you can only go back to "choiceless" state by resetting the form. In Php, when no choice is made the parameter value is unset, or null and is treated, in many respects, as the empty string. The following example illustrates these possibilities:

single-sel.php
<? $file = basename($_SERVER['PHP_SELF']); $title = "Single Selection / external handler ($file)"; ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title><?= $title ?></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="entry.css" /> </head> <body> <h2><?= $title ?></h2> <form action="single-sel-handler.php"> <table class="entry"> <tbody valign="top"> <tr> <td class="left">radio group no pre-selection (<b>rgn</b>)</td> <td> <input type="radio" name="rgn" value="aa">Choice1 <input type="radio" name="rgn" value="bb">Choice2 </td> </tr> <tr> <td class="left">scroll list (<b>scl</b>)</td> <td> <select name="scl" size="3"> <option value="aa">Choice1</option> <option value="bb">Choice2</option> <option value="cc">Choice3</option> </select> </td> </tr> <tr> <td class="left">radio group with pre-selection (<b>rgs</b>)</td> <td> <p>Radio buttons or checkboxes can use label elements <br /> which make clicking the label act like clicking the button. </p> <input type="radio" name="rgs" value="aa" id="r1" checked > <label for="r1" >Choice1</label> <input type="radio" name="rgs" value="bb" id="r2"> <label for="r2" >Choice2</label> </td> </tr> <tr> <td class="left">drop down list (<b>ddl</b>)</td> <td> <select name="ddl"> <option value="aa">Choice1</option> <option value="bb">Choice2</option> <option value="cc">Choice3</option> </select> </td> </tr> </tbody> </table> <input type="submit" value="Submit" name="button" /> <input type="reset" /> </form> </body> </html>

single-sel-handler.php
<?php $param = array_merge( $_GET, $_POST ); $rgn = $param["rgn"]; $rgs = $param["rgs"]; $scl = $param["scl"]; $ddl = $param["ddl"]; $button = $param["button"]; $title = basename($_SERVER['PHP_SELF']); echo <<<END <h2>$title</h2> button: $button</br > rgn: $rgn<br /> scl: $scl<br /> rgs: $rgs<br /> ddl: $ddl<br /> END;

Multiple-Selection Elements

Multiple selection element are those which deliver parameters with multiple values. Again, from a form handler's point-of-view, these are treated in pretty much the same way. In this respect we identify the two elements as being multi-selection elements: In these cases, zero or more choices can be selected yielding a parameter whose value is either unset, if nothing is chosen, or multi-valued, if more than one is chosen. Given any preset choices, we can always go back to nothing being chosen.

In order to retrieve the multiple values in Php, such parameter names must append the [] suffix; this is the only way in which Php will build an array of multiple selected values. If no choices are made the parameter value is unset, or null. One usually has to be careful to avoid using such values in operations which request an array, such as the join operation in which a null input will cause an error.

The following example illustrates some of these possibilities:

multi-sel.php
<? $file = basename($_SERVER['PHP_SELF']); $title = "Multi Selection with external handler ($file)"; ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title><?= $title ?></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="entry.css" /> </head> <body> <h2><?= $title ?></h2> <form action="multi-sel-handler.php"> <table class="entry"> <tbody valign="top"> <tr> <td class="left">checkbox group (<b>cbg</b>)</td> <td> <input type="checkbox" name="cbg[]" value="aa">Choice1 <input type="checkbox" name="cbg[]" value="bb">Choice2 <input type="checkbox" name="cbg[]" value="cc">Choice3 </td> </tr> <tr> <td class="left">multi-select scroll list (<b>msc</b>)</td> <td> <select name="msc[]" size="3" multiple> <option value="aa">Choice1</option> <option value="bb">Choice2</option> <option value="cc">Choice3</option> </select> </td> </tr> </tbody> </table> <input type="submit" value="Submit" name="button" /> </form> </body> </html>

multi-sel-handler.php
<? $param = array_merge( $_GET, $_POST ); $cbg = $param["cbg"]; $msc = $param["msc"]; $button = $param["button"]; $title = basename($_SERVER['PHP_SELF']); echo "<h2>$title</h2>"; echo "button: $button</br >"; echo "cbg: "; print_r($cbg); echo "<br />"; echo "msc: "; print_r($msc); echo "<br />"; ?>

Reentrant forms

The term reentrant means that the form call itself as the action handler. The easiest way to create the reentrant effect is to make the action attribute empty:
<form>
Some authors prefer to make the self-calling explicit by writing this:
<form action="<?= $_SERVER['PHP_SELF'] ?>" >
Often we want to differentiate between the initial activation of the script (typically with no parameters) and the reentrant activations which do have parameters. We can do so by testing whether a certain parameter (often a button's name) is defined or not.

Stable vs. unstable form elements

A static form element, without any programming feature, used in a reentrant script is unstable because it does not preserve any user modifications on a reentrant call. A programmed element which does preserve the input settings on reentry is stable. Creating stability implies that we have to capture the parameter value(s) set by the form, and use these values to reset the form elements accordingly. The method of achieving this effect depends on the element:

Sample Reentrant Scripts


text-reentrant.php
<?php $param = array_merge( $_GET, $_POST ); // The top portion of a script represents the "controller" part. // Here we operation primarily in "Php mode" and capture the // incoming parameters and other server information in order to // use it for various computations and database accesses. $tf = $param["tf"]; $ta = $param["ta"]; $button = $param["button"]; $call = $param['call']; // The code below, with its HTML emphasis, represents the "view" part // in which we create the user presentation. $tf = htmlspecialchars($tf); // prepare these for reentry into the form $ta = htmlspecialchars($ta); $file = basename(__FILE__); $title = "Text: stable reentrant ($file)"; ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title><?= $title ?></title> <link rel="stylesheet" type="text/css" href="entry.css" /> </head> <body> <h2><?= $title ?></h2> <blockquote class="feedback"> <? echo "referer: ", basename($_SERVER['HTTP_REFERER']), "<br />"; echo "button: $button</br >"; echo "(reentrant) call: $call<br />"; echo "tf: $tf<br />"; echo "ta: $ta<br />"; ++$call; ?> </blockquote> <form> <table class="entry"> <tbody valign="top"> <tr> <td class="left">text field (tf):</td> <td><input type="text" class="text" name="tf" value="<?= $tf ?>"/></td> </tr> <tr> <td class="left">text area (ta):</td> <td> <textarea name="ta" rows="10"><?= $ta ?></textarea> </td> </tr> </tbody> </table> <input type="submit" name="button" value="Submit"/> <input type="hidden" name="call" value="<?= $call ?>" /> </form> </body> </html>

single-sel-reentrant.php
<?php $param = array_merge( $_GET, $_POST ); $rgn = $param["rgn"]; $ddl = $param["ddl"]; $button = $param["button"]; $file = basename(__FILE__); $title = "Single Selection: stable reentrant ($file)"; ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title><?= $title ?></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="entry.css" /> </head> <body> <h2><?= $title ?></h2> <blockquote class="feedback"> <? echo "button: $button</br >"; echo "rgn: $rgn<br />"; echo "ddl: $ddl<br />"; ?> </blockquote> <? $entries = array("aa" => "Choice1", "bb" => "Choice2", "cc" => "Choice3",); ?> <form> <table class="entry"> <tbody valign="top"> <tr> <td class="left">radio group no selection (<b>rgn</b>)</td> <td> <? foreach( $entries as $value => $label ): $isChecked = ($value == $rgn) ? "checked" : ""; ?> <input type="radio" name="rgn" value="<?= $value ?>" <?= $isChecked ?> > <?= $label ?> <? endforeach ?> </td> </tr> <tr> <td class="left">drop down list (<b>ddl</b>)</td> <td> <select name="ddl"> <? foreach( $entries as $value => $label ): $isSelected = ($value == $ddl) ? "selected" : ""; ?> <option value="<?= $value ?>" <?= $isSelected ?> > <?= $label ?> </option> <? endforeach ?> </select> </td> </tr> </tbody> </table> <input type="submit" value="Submit" name="button" /> </form> </body> </html>

multi-sel-reentrant.php
<? $param = array_merge( $_GET, $_POST ); $cbg = $param["cbg"]; $msc = $param["msc"]; $button = $param["button"]; $file = basename($_SERVER['PHP_SELF']); $title = "Multi Selection: stable reentrant ($file)"; ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title><?= $title ?></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="entry.css" /> </head> <body> <h2><?= $title ?></h2> <blockquote class="feedback"> <? echo "button: $button</br >"; echo "cbg: "; print_r($cbg); echo "<br />"; echo "msc: "; print_r($msc); echo "<br />"; ?> </blockquote> <? $entries = array("aa" => "Choice1", "bb" => "Choice2", "cc" => "Choice3",); ?> <form> <table class="entry"> <tbody valign="top"> <tr> <td class="left">checkbox group (<b>cbg</b>)</td> <td> <? foreach( $entries as $value => $label ): $isChecked = isset($cbg) && in_array($value,$cbg) ? "checked" : ""; ?> <input type="checkbox" name="cbg[]" value="<?= $value ?>" <?= $isChecked ?> > <?= $label ?> <? endforeach ?> </td> </tr> <tr> <td class="left">multi-select scroll list (<b>msc</b>)</td> <td> <select name="msc[]" size="3" multiple> <? foreach( $entries as $value => $label ): $isSelected = isset($msc) && in_array($value,$msc) ? "selected" : ""; ?> <option value="<?= $value ?>" <?= $isSelected ?> > <?= $label ?> </option> <? endforeach ?> </select> </td> </tr> </tbody> </table> <input type="submit" value="Submit" name="button" /> </form> </body> </html>


© Robert M. Kline