Extracting form variables when programming in
Perl is a real task. The variables can be extracted fairly painlessly
using the CGI.pm modules, but there is a lot of work going on under the
hood.
Creating a PHP Form
Extracting form variables when programming in Perl is a real task.
The variables can be extracted fairly painlessly using the CGI.pm
modules, but there is a lot of work going on under the hood. In PHP
form variables just spring to life. If a form has an input statement:
<input type="text" name="FirstName">
We can just simply use $FirstName in our script. However, this
wonderful shortcut is of no value if we don't know the contents of the
name clauses from the submitted form. In a generalized form handler, we
must deal with $FirstName even though we don't know the name of the
variable.
Fortunately, PHP has an associative array containing all the
name/values pairs contained in a form submission. Actually PHP has two
arrays, $HTTP_POST_VARS and $HTTP_GET_VARS.
As you might expect, the first is populated with a form submission
cybercms_problemcybercms_problemusing the post method while the latter
is populated with get method submissions.
The $REQUEST_METHOD environment variable normally
contains a value of either get or post if the script was called from a
form. However, some older servers may not set this variable so we'll
detect which associative array is loaded to determine the form's
submission method.
The function GetFormData performs two tasks. It returns the
appropriate value Post or Get as the first positional parameter. The
second parameter is an associative array containing the submitted data,
including hidden fields. Once the method determination is ascertained,
this scheme frees the script from any additional get/post consideration.
function GetFormData(&$Method,&$FormVariables) {
# Determine if the form used the post or get method and return in $Method
# Return the form's variables as an associative array containing the
# set of Name - Value pairs.
global $HTTP_POST_VARS, $HTTP_GET_VARS;
# POST or GET method used when submitting the form?
$Method = (isset($HTTP_POST_VARS)) ? "Post" : "Get";
# Load the $FormVariables associative array from appropriate array
$FormVariables = ($Method == "Post") ?
$HTTP_POST_VARS : # Post Method Used
$HTTP_GET_VARS; # Get Method Used
} # End of function GetFormData
The two parameters are passed by reference, note the & before
the $ used for both variables. The function call would use the template:
GetFormData($Method, $FormVariables);
You will also notice the Phanatic's penchant for the ternary conditional format.
$ReceivingVariable = (Condition) ? TrueAssignment : FalseAssignment;
A form element by any other name. Displaying form values presents a three-fold problem:
- traversing the $FormVariables array;
- traversing any form element having multiple values; and
- culling out HIDDEN form values.
We'll cover these in turn.
Let's initially explore the first two problems. An associative array
is a set of key/value pairs. The key portion of the $FormVariables
array represents the form component's name clause. Conversely, the
value portion represents what the user inputs or the value clause in a
hidden field.
PHP has a foreach array traversal function. The foreach construct
can be used for associative or indexed arrays. Our form mailer needs a
function to take an associative array as input, traverse the array --
formatting the display of the array on the fly, and finally, return the
formatted HTML. The following is the code snippet for dumping the
$FormVariables, which is an image of either the $HTTP_GET-VARS or $HTTP_POST_VARS array. The same function can be employed to display other associative arrays variables such as environment values.
Both of the function's required parameters are called by reference.
The first parameter is the associative array to be displayed while the
second parameter returns the formatted HTML.
function DisplayArrayVariables(&$FormVariables,&$HTMLVariables) {
$HTMLVariables = "";
foreach ($FormVariables as $Name=>$Value) {
$HTMLVariables .= "<tr><td align=\"right\"><b>$Name: </b></td>\n";
if (gettype($Value) == "array") {
$ArrayComponent = "";
foreach ($Value as $ArrayElement) {
$ArrayComponents .= "$ArrayElement, ";
} # End of foreach ($Value as $ArrayElement)
$Value = substr($ArrayComponents,0,strlen($ArrayComponents)-2);
} # End of if (gettype($Value) == "array")
$HTMLVariables .= "<td><b>$Value</b></td></tr>\n";
} # End of foreach ($FormVariables as $Name=>$Value)
$HTMLVariables = "<table>\n$HTMLVariables\n</table>\n";
} # End of function DisplayArrayVariables
Hidden fields
The soul of a generic form handler is the script's ability to
perform a variety of optional tasks as selected by the designer of the
form. The various options and parameters are passed to the script as
hidden fields. Quite simply, a hidden field has a predetermined value
assigned by the form's designer, but the end-user of the form never
sees the hidden fields unless they look at the document's source code.
The form handler has only one required hidden field: the e-mail
address of the designated recipient receiving the formatted output. The
HTML code might be
<input type="hidden" name="Recipient" value="toc@aol.com">
The hidden fields must appear between the <form> and
</form> tags. As you might suspect, once we're in the script, the
variable $Recipient contains the value toc@aol.com.
Once arriving in the CGI script, the name/value pairs from any
hidden fields are indistinguishable from user-supplied data. We need a
method to determine which of the form's supplied field are control
variables and which are user variables. To distinguish between the two
types, let's call them system variables and user variables. System
variables and values are created by the form designer. User values are
those entered into the form by the user.
Separating the system and user data is a three-part process. First,
select a group of names than can only be used for system variables.
Second, build an associative array containing name(key) parts
representing possible system variable names. Additionally, default
values for those keys, if any, are then initialized. The Phanatic has
his own naming conventions as you can see from the scripts. He prefers
running variable names together and starting each name portion with a
capital letter, something like FirstName. However, even the Phanatic is
willing to recognize that others may have different naming preferences.
Use whatever convention you like, just be consistent.
How about this range of name values:
- all caps;
- all ;ower case;
- proper Case (First letter of each word capitalized);
- words separated by a space, dash, or underscore.
In other words, FirsName, FIRSTNAME, firstname, first name,
First-Name, First Name, and First_Name should all be recognized as the
same system variable name, namely firstname. Here is a snippet from the
StartUp function:
$SystemVariables = array(
# The action variable determines the script's role.
# "M" is mail results to recipient
# "T" test form by displaying form, system, and environment variables
# "A" mail results to recipient and acknowledgment to submitter
action=>"M",
allownamealias=>True, # Allow name aliasing
recipient=>"", # Email recipient - only required hidden field
subject=>"Form Submission", # Email subject
# Cosmetic properties
bgcolor=>"WHITE", # Background color
To accomplish the required naming flexibility, the keys of the
associated array are all specified as lower case with spaces, dashes,
and underscores squeezed out. Now onto the second part, separating the
system and user variables.
To peek ahead a little, the allownamealias field is set to either
true or false indicating whether name aliases are to be allowed. Maybe
you don't want FirstName and first-name to be the same field.
In an earlier function we placed the form's output into an
associative array called $FormVariables. What we want to do now is
traverse the $FormVariable array and transfer any system variables into
the $SystemVariable array. In addition, we want to delete the system
variable information from the $FormVariables array. Since we're now
experts at traversing an associative array, let jump in.
foreach ($FormVariables as $Name=>$Value)
Remember, the $Name value of a system variable can be based on
several different conventions. First, we have to convert the contents
to conform to the values loaded in the StartUp function. Then we test
the converted name by seeing if the converted value is a key value in
the $SystemVariables array. The next two statements perform the
conversion. The first uses a Perl regular expression to replace blanks,
dashes, and underscores with a null value. The second converts the
result to all lower case.
# Replace blanks, dashes, and underscores with nothing.
$TestKey = preg_replace("/( |-|_)/","",$Value);
$TestKey = strtolower($TestKey);
The remainder of the function then determines if $TestKey (the
converted value) resides in the $SystemVariables array. If so, it
inserts the passed value into the array, overwriting any default value.
If it is a system variable the name/value pair in the $FormVariable
array are removed.
if (isset($SystemVariables[$TestKey])) { # Is it a system variable?
$SystemVariables[$TestKey] = $Value; # Use it's value if yes
unset($FormVariables[$Name]); # Remove it from $FormVariables
} # End of if (isset($SystemVariables[$TestKey]))
Summary
We're well on our way with our generic form process script but,
alas, were running out of space. Let's wrap it up for now and add the
bells and whistles next time.
|