Listing 1-6 (Continued)
// Setup the template block
$t->set_block(“page”, “mainBlock” , “main”);
// Set the template variable = value
$t->set_var(“ERRORS”, $errors);
$t->set_var(“NUM1”, $num1);
$t->set_var(“NUM2”, $num2);
$t->set_var(“OPERATOR”, $operator);
$t->set_var(“RESULT”, $result);
// Parse the template block with all
// predefined key=values
$t->parse(“main”, “mainBlock”, false);
// Parse the entire template and
// print the output
$t->pparse(“OUT”, “page”);
?>
The script can be called using a URL such as the following:
http://yourserver/ch1/calc.php?num1=123&operator=%2B&num2=0
The calc.php script produces an output screen, as shown in Figure 1-1, using the
calc.html template stored in ch1/templates.
Figure 1-1: Output of the calc.php script.
If the script is called without one or more inputs, it shows error messages. For
example, say the user forgot to enter the operator, in such a case the output looks
as shown in Figure 1-2.
16 Part I: Designing PHP Applications
03 549669 ch01.qxd 4/4/03 9:24 AM Page 16
Figure 1-2: Output of the calc.php script (calling without an operator).
Similarly, if the operator is division (/) and the second number is 0, then the
divide by zero error message is shown, as in Figure 1-3.
Figure 1-3: Output of calc.php script (divide by zero error message).
So this script is able to catch input errors and even a run-time error caused by
bad user input (divide by zero). But, sadly, this script is violating a design principle
of a practical PHP application. Notice the following lines in the script:
$errors .= “<li>You did not enter number 1.”;
// lines skipped
$errors .= “<li>You did not enter number 2.”;
// lines skipped
$errors .= “<li>You did not enter the operator.”;
// lines skipped
$errors .= “Divide by zero is not allowed.”;
Chapter 1: Features of Practical PHP Applications 17
03 549669 ch01.qxd 4/4/03 9:24 AM Page 17
These error messages are in English and have HTML tags in them. This means if
the end user wasn’t fond of the way the messages were shown, he or she would
have to change them in the code and potentially risk modification of the code that
may result in bugs. Also, what if the end user spoke, say, Spanish, instead of
English? This also means that the end user would have to change the code. A bet-
ter solution is shown in Listing 1-7 and Listing 1-8.
Listing 1-7: calc2.php
<?php
// Enable all error reporting
error_reporting(E_ALL);
require_once(‘calc2.conf’);
require_once(‘calc2.errors’);
// Get inputs from GET or POST request
$num1 = (! empty($_REQUEST[‘num1’])) ? $_REQUEST[‘num1’] : null;
$num2 = (! empty($_REQUEST[‘num2’])) ? $_REQUEST[‘num2’] : null;
$operator = (! empty($_REQUEST[‘operator’])) ?
$_REQUEST[‘operator’] : null;
// Set errors to null
$errors = null;
// If number 1 is not given, error occurred
if ($num1 == null)
{
$errors .= $ERRORS[LANGUAGE][‘NUM1_MISSING’];
}
// If number 2 is not given, error occured
if ($num2 == null) {
$errors .= $ERRORS[LANGUAGE][‘NUM2_MISSING’];
}
// If operator is not given, error occured
if (empty($operator)) {
$errors .= $ERRORS[LANGUAGE][‘OPERATOR_MISSING’];
}
// Set result to null
$result = null;
18 Part I: Designing PHP Applications
03 549669 ch01.qxd 4/4/03 9:24 AM Page 18
// If operation is + do addition: num1 + num2
if (!strcmp($operator, ‘+’))
{
$result = $num1 + $num2;
// If operation is - do subtraction: num1 - num2
} else if(! strcmp($operator, ‘-’)) {
$result = $num1 - $num2;
// If operation is * do multiplication: num1 * num2
} else if(! strcmp($operator, ‘*’)) {
$result = $num1 * $num2;
// If operation is / do division: num1 / num2
} else if(! strcmp($operator, ‘/’)) {
// If second number is 0, show divide by zero exception
if (! $num2) {
$errors .= $ERRORS[LANGUAGE][‘DIVIDE_BY_ZERO’];
} else {
$result = sprintf(“%.2f”, $num1 / $num2);
}
}
// Create a new template object
$t = new Template($TEMPLATE_DIR);
// Set the template file for this object to application’s template
$t->set_file(“page”, $OUT_TEMPLATE);
// Setup the template block
$t->set_block(“page”, “mainBlock” , “main”);
// Set the template variable = value
$t->set_var(“ERRORS”, $errors);
$t->set_var(“NUM1”, $num1);
$t->set_var(“NUM2”, $num2);
$t->set_var(“OPERATOR”, $operator);
$t->set_var(“RESULT”, $result);
// Parse the template block with all predefined key=values
$t->parse(“main”, “mainBlock”, false);
// Parse the entire template and print the output
$t->pparse(“OUT”, “page”);
?>
Chapter 1: Features of Practical PHP Applications 19
03 549669 ch01.qxd 4/4/03 9:24 AM Page 19
The difference between calc.php and calc2.php is that calc2.php doesn’t
have any error messages hard-coded in the script. The calc.php error messages
have been replaced with the following:
$errors .= $ERRORS[LANGUAGE][NUM1_MISSING];
$errors .= $ERRORS[LANGUAGE][NUM2_MISSING];
$errors .= $ERRORS[LANGUAGE][OPERATOR_MISSING];
$errors .= $ERRORS[LANGUAGE][DIVIDE_BY_ZERO];
The calc2.php script loads error messages from the calc2.errors file using the
following line:
require_once(‘calc2.errors’);
The calc.errors file is shown in Listing 1-8.
Listing 1-8: calc2.errors
<?php
// US English
$ERRORS[‘US’][‘NUM1_MISSING’] = “<li>You did not enter number 1.”;
$ERRORS[‘US’][‘NUM2_MISSING’] = “<li>You did not enter number 2.”;
$ERRORS[‘US’][‘OPERATOR_MISSING’] = “<li>You did not enter the operator.”;
$ERRORS[‘US’][‘DIVIDE_BY_ZERO’] = “Divide by zero is not allowed.”;
// Spanish (translated using Google
// Uncomment the following lines to get Spanish error messages
// Also, set LANGUAGE in calc2.conf to ES
// $ERRORS[‘ES’][‘NUM1_MISSING’] = “<li>Usted no incorporoel numero 1”;
// $ERRORS[‘ES’][‘NUM2_MISSING’] = “<li>Usted no incorporoel numero 2.”;
// $ERRORS[‘ES’][‘OPERATOR_MISSING’] = “<li>Usted no inscribioa operador..”;
// $ERRORS[‘ES’][‘DIVIDE_BY_ZERO’] = “Dividase por cero no se permite.”;
?>
The calc2.errors file loads a multidimensional associative array called
$ERRORS. The first dimension is the language and the second dimension is error
code. For example:
$ERRORS[‘US’][‘NUM1_MISSING’] = “<li>You did not enter number 1.”;
‘US’ is shorthand code for the U.S. English language. The NUM1_MISSING is a
code that has the “<li>You did not enter number 1.” error message associated
with it. When the calc2.php script executes a line such as the following:
$errors .= $ERRORS[LANGUAGE][‘NUM1_MISSING’];
20 Part I: Designing PHP Applications
03 549669 ch01.qxd 4/4/03 9:24 AM Page 20