Web Database Applications With Php And Mysql (2nd Edition) [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Web Database Applications With Php And Mysql (2nd Edition) [Electronic resources] - نسخه متنی

David Lane, Hugh E. Williams

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








10.3 Case Study: Using Sessions in Validation




In this section, we use sessions to
improve the user interaction with the phonebook details form
developed in Chapter 8. The improvements focus
on the interaction when the form is submitted and fields fail
validation. We modify the scripts to:

Display error messages interleaved with the
phonebook's entry form widgets.

Use session variables to pass back the submitted fields to the form
generation script, saving the user the trouble of re-keying the data
to correct the errors.



10.3.1 Improving the Phonebook Details Form



We
designed several phonebook scripts in Chapter 8. In Example 8-7, the form
generated by the script collects values to create a new entry. The
script shown in Example 8-9 performs simple
server-side validation of the form data, and inserts a row in the
phonebook table if there are no errors. We
improve these scripts in this section, but the techniques we show you
can be easily adapted to the other phonebook scripts or to any form
pages you've authored.

If validation fails, the script shown in Example 8-9
generates a page to display the errors to the user, and the user then
follows a hypertext link back to the phonebook entry form to reenter
the fields. The solution provided by Example 8-7 and
Example 8-9 has three problems:

The user is forced to reenter the entire phonebook entry form from
scratch when an error is encountered during validation

Example 8-9 displays all the errors in a stand-alone
page with no connection to the form page, so the user cannot easily
see the relation between errors and the original input fields.

The error page generated by Example 8-9
isn't safe from the reload problem described in
Chapter 8.


In this section we develop scripts that make use of session variables
to solve these problems. Rather than displaying the error messages on
a page generated by the validation script, we show you how to display
the errors in red above the appropriate input fields on the data
entry form, as shown in Figure 10-3 (the red text
appears as a light gray in the figure).



Figure 10-3. The phonebook entry form showing error messages

Figure 10-4 shows how the improved form and the
validate scripts interact with session management to communicate
errors and submitted fields.



Figure 10-4. Phonebook entry form and validation

Because the validation script processes the fields collected in the
phonebook form and generates any associated errors, we look at the
changes required for that script first.


10.3.2 The Validation Script


We begin the improvements to the validation script with the changes
required to support an error message session variable and then
discuss how to record the values to pass back to the phonebook entry
form generation code. We then show you the complete structure of the
modified validation script.

10.3.2.1 Improving error messages



The validation script checks each
variable submitted from the phonebook form to make sure data has been
entered. The script shown in Example 8-9 builds up a
template by adding blocks as errors are found. In the modified script
we use in this case study, an associative array is registered instead
to hold error messages associated with each field, providing greater
flexibility when displaying the error messages.

First, we need to initialize the session with a call to
session_start( ) and set up
$errors to hold an array of errors:

// Initialize a session
session_start( );
// Set-up an empty $errors array to hold errors
$errors = array( );

The script then checks each variable and adds an error message to the
associative array $errors if an error is
encountered. The error message array is indexed by the name of the
field being checked. For example, the validation of the surname is
coded as:

// Validate the Surname
if (empty($surname))
$errors["surname"] = "The surname field cannot be blank.";

Once all the fields have been validated, the size of the
$errors array is tested to determine if any errors
were encountered. If the size of the array is zero, we create or
update the row as before, otherwise we carry out several steps as
shown in the following fragment:

// Now the script has finished the validation, check if
// there were any errors
if (count($errors))
{
// Set up a $lastformVars array to store the previously-entered data
$lastformVars = array( );
$lastFormVars["surname"] = $surname;
$lastFormVars["firstname"] = $firstname;
$lastFormVars["phone"] = $phone;
// Save the array as a session variable
$_SESSION["lastFormVars"] = $lastFormVars;
// Store the $errors array as a session variable
$_SESSION["errors"] = $errors;
// Relocate to the phonebook form
header("Location: example.10-5.php");
exit;
}

The setup and use of the lastFormVars array is
discussed in the next section. The remainder of the fragment saves
the $errors array as a session variable and
relocates to the phonebook entry form script.

In Example 8-9, the script itself displays any
errors, and because the request contains variables in a
POST method request, the error page suffers from
the reload problem discussed in Chapter 8. The
script has to display the errors immediately, in isolation, because
without sessions there is no convenient way to save the errors and
retrieve them again when displaying the form. In the validation
script developed here, we relocate to the phonebook entry form (shown
later in Example 10-5) and let it display the errors
held in the session variable $_SESSION["errors"].

10.3.2.2 Saving last-entered values as a session variable



We now show you how to pass the field
data from the validation script back to the phonebook entry form, so
the user does not have to re-key data after an error occurs. The
fields are passed back the session array variable
lastFormVars.

The following code fragment saves each value entered into the form
into a $lastFormVars array, indexed by the name of
the variable. The $lastFormVars array is then
saved as the session variable
$_SESSION["lastFormVars"].

// Set up a $lastformVars array to store the previously-entered data
$lastformVars = array( );
$lastFormVars["surname"] = $surname;
$lastFormVars["firstname"] = $firstname;
$lastFormVars["phone"] = $phone;
// Save the array as a session variable
$_SESSION["lastFormVars"] = $lastFormVars;

When the modified form is run, the most recent values entered from
the session variable $_SESSION["lastFormVars"] are
shown.

The final change needed is to destroy the session when the script
successfully saves a row in the phonebook table:

// Destroy the session 
session_destroy( );

However, your application may make use of the session for other
purposes and you may not want to destroy the session at this point.
If this is the case then you should unset the variables used in these
scripts.

// Clean up the lastFormVars from the session store
unset($_SESSION["lastFormVars"]);

10.3.2.3 The final validation script


Example 10-4 shows the final validation script
derived from Example 8-9.


Example 10-4. The complete validation script derived from Example 8-9

<?php
require 'db.inc';
if (!($connection = @ mysql_pconnect("localhost", "fred", "shhh")))
die("Could not connect to database");
$firstname = mysqlclean($_POST, "firstname", 50, $connection);
$surname = mysqlclean($_POST, "surname", 50, $connection);
$phone = mysqlclean($_POST, "phone", 20, $connection);
// Initialize a session
session_start( );
// Set-up an empty $errors array to hold errors
$errors = array( );
// Validate the Firstname
if (empty($firstname))
$errors["firstname"] = "The firstname field cannot be blank.";
// Validate the Surname
if (empty($surname))
$errors["surname"] = "The surname field cannot be blank.";
// Validate the Phone number. It must have the correct format
$validPhoneExpr = "^([0-9]{2,3}[ ]?)?[0-9]{4}[ ]?[0-9]{4}$";
if (empty($phone) || !ereg($validPhoneExpr, $phone))
$errors["phone"] = "The phone number must be 8 digits in length,.
with an optional 2 or 3 digit area code";
// Now the script has finished the validation, check if
// there were any errors
if (count($errors))
{
// Set up a $lastformVars array to store
// the previously-entered data
$lastformVars = array( );
$lastFormVars["surname"] = $surname;
$lastFormVars["firstname"] = $firstname;
$lastFormVars["phone"] = $phone;
// Save the array as a session variable
$_SESSION["lastFormVars"] = $lastFormVars;
// Store the $errors array as a session variable
$_SESSION["errors"] = $errors;
// Relocate to the phonebook form
header("Location: example.10-5.php");
exit;
}
// If we made it here, then the data is valid
if (!mysql_select_db("telephone", $connection))
showerror( );
// Insert the new phonebook entry
$query = "INSERT INTO phonebook VALUES
(NULL, '{$surname}', '{$firstname}', '{$phone}')";
if (!(@ mysql_query ($query, $connection)))
showerror( );
// Find out the phonebook_id of the new entry
$phonebook_id = mysql_insert_id( );
// Destroy the session
session_destroy( );
// Show the phonebook receipt
header("Location: example.8-5.php?status=T&phonebook_id={$phonebook_id}");
?>


10.3.3 The Phonebook Entry Form Script



Now
let's turn to the changes required for the script
that generates the phonebook entry form shown in Example 8-7. In the last section, we set up two session
variables: $_SESSION["errors"] to hold an
associative array of error messages found by the validation script,
and $_SESSION["lastFormVars"] to hold an
associative array filled with the form values. Both session variables
are read and incorporated into a new form in this section.

10.3.3.1 Displaying previously entered form values



In our update phonebook details form
in Example 8-11, we read data from the
phonebook table and display it in the input
widgets so that the user can amend it. The form uses the array
$row to populate the data entry fields from a
phonebook row when editing an existing entry in
the database. In this section, we adapt this approach to displaying
previously-entered data that has failed validation.

Adapting the approach from Example 8-11 to our
sessions-based script is straightforward. Consider the following
fragment:

$row = array( );
// Has previous data been entered?
// If so, initialize $row from $_SESSION["lastFormVars"]
if (isset($_SESSION["lastFormVars"]))
{
$row = $_SESSION["lastFormVars"];
$template->setVariable("MESSAGE",
"Please correct the errors shown below");
$template->setVariable("SUBMITVALUE", "Try again");
}

If the $_SESSION["lastFormVars"] variable is set,
$row is set to
$_SESSION["lastFormVars"], and a
message and submit button value set to inform the user that errors
have occurred. Then, for each widget in the form, the script displays
the value the user previously entered (or an empty widget if no
previous value was supplied):

if (!empty($row))
$template->setVariable("MINPUTVALUE", $row["firstname"]);
else
$template->setVariable("MINPUTVALUE", ");

10.3.3.2 Displaying error messages



To
display the error messages above the input widgets,
we've modified our phonebook template; the phonebook
template is discussed in more detail in Chapter 8. It now includes the following fragment:

<!-- BEGIN mandatoryinput -->
<tr>
<!-- BEGIN mandatoryerror -->
<td>
<td><font color="red">{MINPUTERROR}</font>
</tr>
<tr>
<!-- END mandatoryerror -->
<td><font color="red">{MINPUTTEXT}:</font></td>
<td>
<input type="text" name="{MINPUTNAME}" value="{MINPUTVALUE}"
size={MINPUTSIZE}>
</td>
</tr>
<!-- END mandatoryinput -->

The mandatoryerror block is an optional block
that's included before the input
element and is used to show an error message in a
red font using the placeholder MINPUTERROR. If no
error occurs, we don't set
MINPUTERROR and don't use the
mandatoryerror block.

To decide whether to display an error message or not, we check the
contents of the
$_SESSION["errors"] array. If
there's an entry for the input name in the
associative array of error messages, we use the
mandatoryerror block and display the message.
Here's an example for the
firstname element:

if (!empty($_SESSION["errors"]["firstname"]))
{
$template->setCurrentBlock("mandatoryerror");
$template->setVariable("MINPUTERROR", $_SESSION["errors"]["firstname"]);
$template->parseCurrentBlock("mandatoryerror");
}

Figure 10-4 shows the final results: a form with
error messages placed over the corresponding fields.

10.3.3.3 The final phonebook entry script


Example 10-5
shows
the complete data entry script, derived from Example 8-7, that displays the previous form values and
the error messages held in session variables. Example 10-6 shows the template.


Example 10-5. Phonebook entry form derived from Example 8-7

<?php
require 'db.inc';
require_once "HTML/Template/ITX.php";
if (!($connection = @ mysql_connect("localhost", "fred", "shhh")))
die("Could not connect to database");
session_start( );
$template = new HTML_Template_ITX("./templates");
$template->loadTemplatefile("example.10-6.tpl", true, true);
$row = array( );
// Has previous data been entered?
// If so, initialize $row from $_SESSION["lastFormVars"]
if (isset($_SESSION["lastFormVars"]))
{
$row = $_SESSION["lastFormVars"];
$template->setVariable("MESSAGE",
"Please correct the errors shown below");
$template->setVariable("SUBMITVALUE", "Try again");
}
else
{
// If they're not correcting an error show a
// "fill in the details" message
$template->setVariable("MESSAGE",
"Please fill in the details below to add an entry");
$template->setVariable("SUBMITVALUE", "Add Now!");
}
$template->setCurrentBlock("mandatoryinput");
$template->setVariable("MINPUTTEXT", "First name");
$template->setVariable("MINPUTNAME", "firstname");
if (!empty($row))
$template->setVariable("MINPUTVALUE", $row["firstname"]);
else
$template->setVariable("MINPUTVALUE", ");
if (!empty($_SESSION["errors"]["firstname"]))
{
$template->setCurrentBlock("mandatoryerror");
$template->setVariable("MINPUTERROR", $_SESSION["errors"]["firstname"]);
$template->parseCurrentBlock("mandatoryerror");
}
$template->setCurrentBlock("mandatoryinput");
$template->setVariable("MINPUTSIZE", 50);
$template->parseCurrentBlock("mandatoryinput");
$template->setCurrentBlock("mandatoryinput");
$template->setVariable("MINPUTTEXT", "Surname");
$template->setVariable("MINPUTNAME", "surname");
if (!empty($row))
$template->setVariable("MINPUTVALUE", $row["surname"]);
else
$template->setVariable("MINPUTVALUE", ");
if (!empty($_SESSION["errors"]["surname"]))
{
$template->setCurrentBlock("mandatoryerror");
$template->setVariable("MINPUTERROR", $_SESSION["errors"]["surname"]);
$template->parseCurrentBlock("mandatoryerror");
}
$template->setCurrentBlock("mandatoryinput");
$template->setVariable("MINPUTSIZE", 50);
$template->parseCurrentBlock("mandatoryinput");
$template->setCurrentBlock("mandatoryinput");
$template->setVariable("MINPUTTEXT", "Phone");
$template->setVariable("MINPUTNAME", "phone");
if (!empty($row))
$template->setVariable("MINPUTVALUE", $row["phone"]);
else
$template->setVariable("MINPUTVALUE", ");
if (!empty($_SESSION["errors"]["phone"]))
{
$template->setCurrentBlock("mandatoryerror");
$template->setVariable("MINPUTERROR", $_SESSION["errors"]["phone"]);
$template->parseCurrentBlock("mandatoryerror");
}
$template->setCurrentBlock("mandatoryinput");
$template->setVariable("MINPUTSIZE", 20);
$template->parseCurrentBlock("mandatoryinput");
$template->setCurrentBlock( );
$template->parseCurrentBlock( );
$template->show( );
?>

Example 10-6. The template to display the phonebook form






<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html401/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Phonebook Details</title>
</head>
<body bgcolor="white">
<form method="post" action="example.10-4.php">
<h1>Phonebook Details</h1>
<h2>{MESSAGE}.
Fields shown in <font color="red">red</font> are mandatory.</h2>
<table>
<!-- BEGIN mandatoryinput -->
<tr>
<!-- BEGIN mandatoryerror -->
<td>
<td><font color="red">{MINPUTERROR}</font>
</tr>
<tr>
<!-- END mandatoryerror -->
<td><font color="red">{MINPUTTEXT}:</font></td>
<td>
<input type="text" name="{MINPUTNAME}" value="{MINPUTVALUE}"
size={MINPUTSIZE}>
</td>
</tr>
<!-- END mandatoryinput -->
<tr>
<td><input type="submit" value="{SUBMITVALUE}"></td>
</tr>
</table>
</form>
</body>
</html>


/ 176