Download the
PhpForms.zip archive.
Extract/install it into your default website folder
and set it up as
a NetBeans
Php Project with Existing Sources
as described
in the Php Basics document.
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.
Stacking
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 URL 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 without
browser refreshing, thereby avoid stacking.
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 former hyperlink to "some-url"
is equivalent to this usage with the JavaScript location object:
User-generated web data is transmitted as a list
of parameters/values in a data string constructed like this:
name1=value1&name2=value2&...
where name1, name2, etc., typically correspond
to the names of form elements and the
values are generated by the user
in text entries or selection 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 queries are simpler to understand and debug
by virtue of the data being part of the URL.
GET queries are thus more easily "repeatable."
Users can easily bookmark GET queries and
thereby remember and communicate web "finds" in through them.
For security reasons, some servers do not want to permit
handling data through POST requests; so if you're sending form
information to an external server (over which you have no control),
it's best to use GET.
POST queries, by virtue of sending data through standard output, and
not through the URL, are more secure for password entry, etc. Additionally,
POST queries permit larger amounts of data to be transmitted, say, as
documents loaded in a text area or via file upload.
GET method is the method used by standard hyperlink activations.
and 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:
Web activations which have side effects, such as update, add, delete
of data should be POST.
Web activations involving transmission of sensitive data, such as
passwords, should be POST.
Web activations involving transmission of large amounts of
data (file uploads, document submissions) should be POST.
Web activations which generate the search/display of data should
be GET queries.
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 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:
$_SERVER['REQUEST_METHOD'] = the type of HTTP request, either GET or POST.
$_SERVER['QUERY_STRING'] = portion of URL following the ?; input to a script
$_SERVER['SCRIPT_FILENAME'] = the full path of the script
$_SERVER['SCRIPT_NAME'] = the URL without query string
$_SERVER['PHP_SELF'] = the URL without query string
$_SERVER['REQUEST_URI'] = the full URL with query string
$_SERVER['REMOTE_ADDR'] = the IP address of the "caller"
$_SERVER['HTTP_REFERER'] = the URL which "called" this script
$_SERVER['SERVER_NAME'] = the name of the Web server host
A simple program which prints out the $_SERVER array is this:
<form action="PROGRAM" method="METHOD" target="TARGET">
<!-- form elements -->
</form>
where
PROGRAM is what is called when the form is submitted;
this is some type of program which will process the information
sent through form parameters
METHOD is either GET (parameters passed through query string in URL)
or POST (parameters passed through standard input)
TARGET indicates where the action SCRIPT
will display. The default is to display in the frame containing
the form but can be targetted to a different frame; there
are 4 predefined targets:
_blank: always to a new browser window
_parent: the parent in a frameset
_self: the window/frame containing the form (this is the default)
_top: the top in a frameset
Form Components
The HTML form components provide the user interface. They consist of
buttons: used to submit the form.
textfields and password fields: single line inputs
textareas: multi-line inputs
check boxes and radio buttons:
allow the user to say yes/no to a choice, or one of several choices.
selection lists: these give a choice through a popup or
scroll list
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.
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:
onclick
mouse 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/onkeyup
a 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:
where the NAME identifies the parameter name
passed to the action script.
These are also used to control behavior ot textfields and textareas:
readonly: boolean attribute for textfields
size: integer for textfields
maxlength: integer: maximum number chars for textfields
tabindex: integer position in tabbing order
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 uses magic quotes.
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"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:
"<",
"&",
""",
">".
You can:
leave the characters alone, assuming that the input is
to be rendered as HTML
translate the characters into HTML special sequences
< <
& &
" "
> >
so that they are rendered literally
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:
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,
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:
as indicated, try the "problematic" inputs
with both buttons
add method="post" in the
form start tag, rerun and observe the difference.
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<b>c"d<br />
ta: a</textarea>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>
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:
TYPE is radio, this is a radio button;
elements of the same NAME are mutually exclusive.
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:
size="SIZE": an integer.
If SIZE is 1 (the default),
the selection is a drop-down list, like the Java ComboBox.
If SIZE > 1 the selection is a scrolling list
multiple: a boolean attribute which, if present,
permits multiple selection from the list, making the
parameter multi-valued.
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:
radio groups
single-selection lists (i.e., the multiple attribute is not present)
A second distinction among these single-selection elements is this:
those with one pre-selected element, one of three possibilities:
a radio group with one choice checked
a selection list of size 1 (by default the first item is selected)
a selection list of any size with one option selected
those with no pre-selected element, one of two possibilities:
a radio group with no choices checked
a selection list of size > 1
with no options selected
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>
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:
checkbox groups (more than one checkbox with same name)
multi-selection lists
(i.e., the multiple is present, there are more than one
option, and the size attribute usually has a value
> 1)
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:
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 action="">
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:
Textfield: set value="the (escaped) parameter value"
Textarea: insert the (escaped) parameter value between the
start and end textarea tags
Radio group: loop through the radio button values, test for
equality with the parameter value, and set to checked when true
Single-selection list: loop through the option values, test for
equality with the parameter value, and set to selected when true
Checkbox group, multi-selection list: same respective ideas
as with a radio group and single-selection list, except that there
is set of parameter values to which the generated value may belong.
Use the in_array function to see if the generated
value, $value, is in the array, $p,
of parameter values. Since $p can be unset,
the usage is typically this:
$p = $param['p']; // null, or an array
if ( isset($p) && in_array($value,$p) )
/* then this checkbox/option should be checked/selected */
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 action="">
<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>