April 5, 2008
WikiChapter 1
Chapter 1
Web database applications built around a three-tier architecture model. At the base of an application is the database tier, consisting of the database management system that manages the database containing the data users create, delete, modify, and query. Built on top of the database tier is the complex middle tier, which contains most of the application logic and communicates data between the other tiers. On top is the client tier, usually web browser software that interacts with the application.
When we use the term “the Web,” we mean three major, distinct standards and the tools based on these standards: the Hypertext Markup Language (HTML), the Hypertext Transfer Protocol (HTTP), and the TCP/IP networking protocol suite. HTML works well for structuring and presenting information using a web browser application. TCP/IP is an effective networking protocol that transfers data between applications over the Internet and has little impact on web database application developers. The problem in building web database applications is interfacing traditional database applications to the Web using HTTP. This is where the complex application logic is needed.
HTTP allows resources to be communicated and shared over the Web. From a network perspective, HTTP is an applications-layer protocol that is built on top of the TCP/IP networking protocol suite. Most web servers and web browsers communicate using the current version, HTTP/1.1. Some browsers and servers use the previous version, HTTP/1.0, but most HTTP/1.1 software is backward-compatible with HTTP/1.0.
HTTP communications dominate Internet network traffic. In 1997, HTTP accounted for about 75% of all traffic.[1] We speculate that this percentage is now even higher due to the growth in the number and popularity of HTTP-based applications such as free email services.
[1] From K. Thompson, G. J. Miller, and R. Wilder. “Wide-area internet traffic patterns and characteristics,” IEEE Network, 11(6):10-23, November/December 1997.
An HTTP request is a textual description of a resource and additional header information. Consider the following example request:
GET /index.html HTTP/1.0
From: hugh@computer.org (Hugh Williams)
User-agent: Hugh-fake-browser/version-1.0
Accept: text/plain, text/html
This example uses a GET method to request an HTML page index.html with HTTP/1.0. In this example, three additional header lines identify the user and the web browser and define what data types can be accepted by the browser. A request is normally made by a web browser and may include other headers; the previous example was created manually by typing the request into Telnet software.
An HTTP response has a response code and message, additional headers, and usually the resource that has been requested. An example response to the request for index.html is as follows:
HTTP/1.0 200 OK
Date: Sat, 21 Jul 2002 03:44:25 GMT
Server: Apache/1.3.20
Content-type: text/html
Content-length: 88
Last-modified: Fri, 1 Feb 2002 03:40:03 GMT
<html><head>
<title>Test Page</title></head>
<body>
<h1>It Worked!</h1>
</body></html>
The first line of the response agrees to use HTTP/1.0 and confirms that the request succeeded by reporting the response code 200 and the message OK; another common response is 404 Not Found. In this example, five lines of additional headers identify the current date and time, the web server software, the data type, the length of the response, and when the resource was last modified. After a blank line, the resource itself follows. In this example the resource is the requested HTML document, index.html.
State
Traditional database applications are stateful. In traditional database applications, users log in, run related transactions, and then log out when they are finished. For example, in a bank application, a bank teller might log in, use the application through a series of menus as he serves customer requests, and log out when he’s finished for the day. The bank application has state: once the teller is logged in, he can interact with the application in a structured way using menus. When the teller has logged out, he can no longer use the application.
HTTP is stateless. Statelessness means that any interaction between a web browser and a web server is independent of any other interaction. Each HTTP request from a web browser includes the same header information, such as the security credentials of the user, the types of pages the browser can accept, and instructions on how to format the response. Statelessness has benefits: the most significant are the resource savings from not having to maintain information at the web server to track a user, and the flexibility to allow users to move between unrelated pages or resources.
Because HTTP is stateless, it is difficult to develop stateful web database applications. What is needed is a method to maintain state in HTTP so that information flows and structure can be imposed. A common solution is to exchange a token between a web browser and a web server that uniquely identifies the user and her session. Each time a browser requests a resource, it presents the token, and each time the web server responds, it returns the token to the web browser. The token is used by the middle-tier software to restore information about a user from her previous request, such as which menu in the application she last accessed. Exchanging tokens allows stateful structure such as menus, steps, and workflow processes to be added to the application.
Thin Clients
1.1.2 Thin Clients
Given that a web database application built with a three-tier architecture doesn’t fit naturally with HTTP, why use that model at all? The answer mostly lies in the benefits of the thin client. Web browsers are very thin clients: little application logic is included in the client tier. The browser simply sends HTTP requests for resources and then displays the responses, which contain mostly HTML documents.
A three-tier model means you don’t have to build, install, or configure the client tier. Any user who has a web browser can use the web database application, usually without needing to install additional software, be using a specific operating system, or own a particular hardware platform. This means an application can be delivered to any number of diverse, geographically dispersed users. The advantage is so significant that our focus in this book is entirely on three-tier solutions with this thin-client web browser architecture.
But what are the alternatives to a thin client? A custom-built Java applet is an example of a thicker client that can still fit the three-tier model: the user downloads an applet and runs more of the overall application logic on her platform. The applet still interacts with a middle tier that, in turn, provides an interface to the database tier. The advantage is customization: rather than using the generic browser solution, a custom solution can eliminate many problems inherent in the statelessness, security, and inflexibility of the Web. The applet might not even use HTTP to communicate with the middle-tier application logic.
A thick client is also part of a traditional two-tier solution, also known as a client/server architecture. Most traditional database applications—such as those in the bank—have only two tiers. The client tier has most of the overall application logic, and the server tier is the DBMS itself. The advantage is that a customized solution can be designed to meet the exact application requirements without any compromises. Disadvantages are the lack of hardware and operating system flexibility and the requirement to provide software to each user.
When a user agent makes a request to the web server for a PHP script, six steps occur:
The web server passes the request to the Zend engine’s web server interface.
The web server interface calls the Zend engine and passes parameters to the engine.
The PHP script is retrieved from disk by the engine.
The script is compiled by the runtime compiler.
The compiled code is run by the engine’s executor and may include calls to function modules. The output of the executor is returned to the web server interface.
The web server interface returns output to the web server (which, in turn, returns the output as an HTTP response to the user agent).
How the PHP scripting engine is managed and run depends on how the PHP module is included in the Apache web server installation process.
The Database Tier
In a three-tier architecture application, the database tier manages the data. The data management typically includes storage and retrieval of data, as well as managing updates, allowing simultaneous, or concurrent, access by more than one middle-tier process, providing security, ensuring the integrity of data, and providing support services such as data backup. In many web database applications, these services are provided by a RDBMS system, and the data stored in a relational database.
Managing relational data in the third tier requires complex RDBMS software. Fortunately, most DBMSs are designed so that the software complexities are hidden. To effectively use a DBMS, skills are required to design a database and formulate commands and queries to the DBMS. For most DBMSs, the query language of choice is SQL. An understanding of the underlying architecture of the DBMS is unimportant to most users.
Database Management Systems
A database management system stores, searches, and manages data.
A database is a collection of related data. The data stored can be a few entries, or rows, that make up a simple address book of names, addresses, and phone numbers. In contrast, the database can also contain millions of records that describe the catalog, purchases, orders, and payroll of a large company.
A DBMS is a set of components for defining, constructing, and manipulating a database. When we refer to a database management system, we generally mean a relational DBMS or RDBMS. Relational databases store and manage relationships between data—for example, customers placing orders, customer orders containing line items, or wineries being part of a wine-growing region.
Chapter 2
One of the convenient features of PHP is the ability to include the value of a variable in a string literal. PHP parses double-quoted strings and replaces variable names with the variable’s value. The following example shows how:
$number = 45;
$vehicle = "bus";
$message = "This $vehicle holds $number people";
// prints "This bus holds 45 people"
echo $message;
Variables
Variables in PHP are identified by a dollar sign followed by the variable name. Variables don’t need to be declared, and they have no type until they are assigned a value. The following code fragment shows a variable $var assigned the value of an expression, the integer 15. Therefore, $var is defined as being of type integer.
$var = 15;
The variable type can change over the lifetime of the variable. Consider an example:
$var = 15;
$var = "Sarah the Cat";
This fragment is acceptable in PHP. The type of $var changes from integer to string as the variable is reassigned. Letting PHP change the type of a variable as the context changes is very flexible and a little dangerous.
Types
PHP has four scalar types—boolean, float, integer, and string—and two compound types, array and object.
Constants
Constants associate a name with a simple, scalar value. For example, the Boolean values true and false are constants associated with the values 1 and 0, respectively. It’s also common to declare constants in a script. Consider this example constant declaration:
define("pi", 3.14159);
// This outputs 3.14159
echo pi;
Constants aren’t preceded by a $ character; they can’t be changed once they have been defined; they can be accessed anywhere in a script, regardless of where they are declared; and they can only be simple, scalar values.
Constants are useful because they allow parameters internal to the script to be grouped. When one parameter changes—for example, if you define a new maximum number of lines per web page—you can alter this constant parameter in only one place and not throughout the code.
String assignments and expressions are similar:
// Assign a string value to a variable
$var = "test string";
// Concatenate two strings together
// to produce "test string"
$var = "test" . " string";
// Add a string to the end of another
// to produce "test string"
$var = "test";
$var = $var . " string";
// Here is a shortcut to add a string to
// the end of another
$var .= " test";
During the running of a PHP script, a variable may be in an unset state or may not yet be defined. PHP provides the isset( ) function and the empty( ) language construct to test the state of variables:
boolean isset(mixed var) boolean empty(mixed var) isset( ) tests if a variable has been set with a non-null value, while empty( ) tests if a variable has a value. The two are different, as shown by the following code:
$var = "test";
// prints: "Variable is Set"
if (isset($var)) echo "Variable is Set";
// does not print
if (empty($var)) echo "Variable is Empty";
//A variable can be explicitly destroyed using unset( ):
unset(mixed var [, mixed var [, ...]])
//After the call to unset in the following example, $var is no longer defined:
$var = "foo";
// Later in the script
unset($var);
// Does not print
if (isset($var)) echo "Variable is Set";
Another way to test that a variable is empty is to force it to the Boolean type using the (bool) cast operator discussed earlier. The example interprets the $var variable as type Boolean, which is equivalent to testing for !empty($var):
$var = "foo";
// Both lines are printed
if ((bool)$var) echo "Variable is not Empty";
if (!empty($var)) echo "Variable is not Empty";
Arrays
Arrays in PHP are sophisticated and more flexible than in many other high-level languages. An array is an ordered set of variables, in which each variable is called an element. Technically, arrays can be either numbered or associative, which means that the elements of an array can be accessed by a numeric index or by a textual string, respectively.
In PHP, an array can hold scalar values—integers, Booleans, strings, or floats—or compound values—objects and even other arrays, and can hold values of different types. In this section, we show how arrays are constructed and introduce several useful array functions from the PHP library.
PHP provides the array( ) language construct that creates arrays. The following examples show how arrays of integers and strings can be constructed and assigned to variables for later use:
$numbers = array(5, 4, 3, 2, 1);
$words = array("Web", "Database", "Applications");
// Print the third element from the array
// of integers: 3
echo $numbers[2];
// Print the first element from the array
// of strings: "Web"
echo $words[0];
Associative arrays
An associative array uses string indexes—or keys—to access values stored in the array. An associative array can be constructed using array( ), as shown in the following example, which constructs an array of integers:
$array = array("first"=>1, "second"=>2, "third"=>3);
// Echo out the second element: prints "2"
echo $array["second"];
// The same array of integers can also be created with the bracket syntax:
$array["first"] = 1;
$array["second"] = 2;
$array["third"] = 3;
There is little difference between using numerical or string indexes to access values. Both can reference elements of an associative array, but this is confusing and should be avoided in practice.
Associatively indexed arrays are particularly useful for interacting with the database tier.
Heterogeneous arrays
The values that can be stored in a single PHP array don’t have to be of the same type; PHP arrays can contain heterogeneous values. The following example shows the heterogeneous array $mixedBag:
$mixedBag = array("cat", 42, 8.5, false);
var_dump($mixedBag); The function var_dump( ) displays the contents (with a little whitespace added for clarity):
array(4) { [0]=> string(3) "cat"
[1]=> int(42)
[2]=> float(8.5)
[3]=> bool(false) }
## Multidimensional arrays
<!DOCTYPE HTML PUBLIC
"-*W3C*DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd" >
<html>
<head>
<title>Multi-dimensional arrays</title>
</head>
<body bgcolor="#ffffff">
<h2>A two dimensional array</h2>
<?php
// A two dimensional array using integer indexes
$planets = array(array("Mercury", 0.39, 0.38),
array("Venus", 0.72, 0.95),
array("Earth", 1.0, 1.0),
array("Mars", 1.52, 0.53) );
// prints "Earth"
print $planets[2][0]
?>
<h2>More sophisticated multi-dimensional array</h2>
<?php
// More sophisticated multi-dimensional array
$planets2 = array(
"Mercury"=> array("dist"=>0.39, "dia"=>0.38),
"Venus" => array("dist"=>0.39, "dia"=>0.95),
"Earth" => array("dist"=>1.0, "dia"=>1.0,
"moons"=>array("Moon")),
"Mars" => array("dist"=>0.39, "dia"=>0.53,
"moons"=>array("Phobos", "Deimos")),
);
// prints "Moon"
print $planets2["Earth"]["moons"][0];
?>
</body>
</html>
The first array constructed in Example 2-4 is two-dimensional and is accessed using integer indexes. The array $planets contains four elements, each of which is an array that contains three values: the planet name, the distance from the Sun, and the planet diameter relative to the Earth.
The second array in Example 2-4 is a little more sophisticated: the array $planets2 uses associative keys to identify an array that holds information about a planet. Each planet has an array of values that are associatively indexed by the name of the property that is stored; the array is effectively acting like a property list. For those planets that have moons, an extra property is added that holds an array of the moon names.
As stated in the introduction to this section, PHP arrays are very flexible. Many data structures—such as property lists, stacks, queues, and trees—can be created using arrays. We limit our usage of arrays to simple structures; the examination of more complex data structures is outside the scope of this book.
Using foreach Loops with Arrays
As we discussed earlier, the easiest way to iterate through—or traverse—an array is using the foreach statement.The foreach statement was specifically introduced in PHP4 to make working with arrays easier.
The foreach statement has two forms:
foreach(array_expression as $value) statement
foreach(array_expression as $key => $value) statement
Both iterate through an array expression, executing the body of the loop for each element in the array. The first form assigns the value from the element to a variable identified with the as keyword; the second form assigns both the key and the value to a pair of variables.
The following example shows the first form in which the array expression is the variable $lengths, and each value is assigned to the variable $cm:
// Construct an array of integers
$lengths = array(0, 107, 202, 400, 475);
// Convert an array of centimeter lengths to inches
foreach($lengths as $cm)
{
$inch = $cm / 2.54;
echo "$cm centimeters = $inch inches\n";
}
The example iterates through the array in the same order it was created:
0 centimeters = 0 inches
107 centimeters = 42.125984251969 inches
202 centimeters = 79.527559055118 inches
400 centimeters = 157.48031496063 inches
475 centimeters = 193.87755102041 inches
The first form of the foreach statement can also iterate through the values of an associative array, however the second form assigns both the key and the value to variables identified as $key => $value. The next example shows how the key is assigned to $animal, and the value is assigned to $sound to generate verses of “Old MacDonald”:
// Old MacDonald
$sounds = array("cow"=>"moo", "dog"=>"woof",
"pig"=>"oink", "duck"=>"quack");
foreach ($sounds as $animal => $sound)
{
echo "<p>Old MacDonald had a farm EIEIO";
echo "<br>And on that farm he had a $animal EIEIO";
echo "<br>With a $sound-$sound here";
echo "<br>And a $sound-$sound there";
echo "<br>Here a $sound, there a $sound";
echo "<br>Everywhere a $sound-$sound";
}
This prints a verse for each $animal/$sound pair in the $sounds array:
Old MacDonald had a farm EIEIO
And on that farm he had a cow EIEIO
With a moo-moo here
And a moo-moo there
Here a moo, there a moo
Everywhere a moo-moo
Old MacDonald had a farm EIEIO
And on that farm he had a dog EIEIO
With a woof-woof here
And a woof-woof there
Here a woof, there a woof
Everywhere a woof-woof
When the second form of the foreach statement is used with a nonassociative array, the index is assigned to the key variable and the value to the value variable. The following example uses the index to number each line of output:
// Construct an array of integers
$lengths = array(0, 107, 202, 400, 475);
// Convert an array of centimeter lengths to inches
foreach($lengths as $index => $cm)
{
$inch = $cm / 2.54;
$item = $index + 1;
echo $index + 1 . ". $cm centimeters = $inch inches\n";
}
Continue Reading
Back to Archive