Building Applications That Keep State - Page 2
April 24, 2002
Applications sometimes need to use the result of one request when
processing another. For example, a request that adds an item to a shopping
cart needs to be remembered when the request is made to create the order. In
other words, the state of the application needs to be stored between HTTP
requests. There are two ways to achieve this: variables that hold the state
can be stored in the browser and included with each request or variables can
be stored on the server.
Most of this chapter is devoted to the second alternative, where the middle
tier stores and manages the application state using sessions. However, in this
section we briefly discuss solutions that store state in the client tier. One
technique described in this section is the use of cookies. While cookies can
store state in the client tier, they are also used in middle-tier session
management, as described later in this chapter.
Managing State in the Client Tier
Data sent with the GET or POST methods can
include the application state with each HTTP request. An illustration of this
approach can be seen in the previous and next browsing features developed in
Chapter 5. In this example, there are two pieces, or states, that
need to be considered when a page is browsed: the query parameters the user
provided and which page should be displayed.
The solution developed in Chapter 5 encodes the query and an offset as an
embedded link. An example URL that displays the fourth page of results may be
as follows:
http://localhost/example.5-10.php?regionName=All&offset=40
This solution allows navigation through large search result sets. Similar
solutions are used in the URLs generated to jump between the results pages of
web search engines such as Google or Altavista. Cookies can be used for the
same purpose.
Encoding the variables that hold state with each HTTP request increases the
amount of data that has to be transmitted over the Web, and when data is
encoded using the GET method, applications can generate long
URLs. While HTTP doesn't restrict the length of URLs, some older browsers and
proxy servers do enforce limits.
When state variables are encoded as part of the URL, or even when they are
included as cookies, it is possible for the user to change the values that are
sent with the request. For example, a user can enter the following URL
manually if she wants to see the records starting from row #7 in the result
set:
http://localhost/example.5-10.php?regionName=All&offset=7
Changing the offset in a results page is harmless, but changing the item
price of a bottle of wine is more serious. As discussed in Chapters 6 and 7,
an application can't rely on data that is sent from the browser.
Cookies
Cookies are often used to store application state in a web browser. As with
data sent with the GET or POST methods, cookies are
sent with HTTP requests made by a browser. A cookie is a named piece
of information that is stored in a web browser. A browser can create a cookie
using JavaScript, but a cookie is usually sent from the web server to the
client in the Set-Cookie header field as part of an HTTP
response. Consider an example HTTP response:
HTTP/1.0 200
Content-Length: 1276
Content-Type: text/html
Date: Tue, 06 Nov 2001 04:12:49 GMT
Expires: Tue, 06 Nov 2001 04:12:59 GMT
Server: simwebs/3.1.6
Set-Cookie: animal=egg-laying-mammal
<html>...</html>
The web browser that receives this response remembers the cookie and
includes it as the header field Cookie in subsequent HTTP
requests to the same web server. For example, if a browser receives the
response just shown, a subsequent request has the following format:
GET /duck/bill.php HTTP/1.0
Connection: Keep-Alive
Cookie: animal=egg-laying-mammal
Host: www.webdatabasebook.com
Referer: http://www.webdatabasebook.com/
There are several additional parameters used with the
Set-Cookie header that define when a cookie can be included in a
request:
- A cookie can have a date and time at which it expires. The browser
includes the cookie in requests up until that date and time. If no expiry
date is given, the cookie is remembered only while the browser is running.
Cookies that are kept only while the browser is running are known as
session cookies.
- A
domain limits the sites to which a browser can send the
cookie. If no domain is set, the browser includes the cookie
only in requests sent to the server that set the cookie.
- Browsers don't include the cookie in requests for resources that aren't
in the specified
path. This is useful if only part of a web
site requires that a cookie be sent. For example, if the path is set to
/admin, requests for resources in that path, such as
http://localhost/admin/home.php include the cookie, while requests
for resources in other paths, such as
http://localhost/winestore/home.php, do not.
- A cookie can also be marked as
secure, instructing the
browser to send the cookie only when using a secure connection through the
Secure Sockets Layer protocol. This prevents sensitive data stored in a
cookie from being transmitted in an insecure form. Encryption using the SSL
software is discussed in Chapter 9.
Cookies can be included in an HTTP response using the header(
) function; however, the developer needs to know how to encode the
cookie name, value, and the other parameters described earlier in the
Set-Cookie header field. To simplify cookie creation, PHP
provides the setcookie( ) function that generates a correct
header field.
When an HTTP request that contains cookies is processed, PHP makes the
values of the cookies available to the script in the global associative array
$HTTP_COOKIE_VARS. If register_globals is enabled, a
variable with the name of the cookie is also initialized by PHP; the
register_globals feature in the php.ini file is
discussed in Chapter 5.Example
8-1 tests to see if the variable $count has been set from a
cookie, and either sets the value to 0 or increments $count
accordingly. The script also creates a cookie named start, with
the value set to the current time, when the $count is set to 0.
The cookie start is set only at the beginning of this stateful
interaction.
Example 8-1: Setting a cookie using PHP
<?php
// See if the HTTP request has set $count as the
// result of a Cookie called "count"
if(!isset($count)) {
// No cookie called count, set the counter to zero
$count = 0;
// .. and set a cookie with the "start" time
// of this stateful interaction
$start = time( );
setcookie("start", $start, time( )+600, "/", "", 0);
} else {
$count++;
}
// Set a cookie "count" with the current value
setcookie("count", $count, time( )+600, "/", "", 0);
?>
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd" >
<html>
<head><title>Cookies</title></head>
<body>
<p>This page comes with cookies: Enjoy!
<br>count = <?=$count ?>.
<br>start = <?=$start ?>.
<p>This session has lasted
<?php
$duration = time( ) - $start;
echo "$duration";
?>
seconds.
</body>
</html>
The setcookie( ) function is called with six arguments,
although only the first--the name--is required:
int setcookie(string name, [string value],
[int expire], [string path], string domain, [int secure])
The two calls to setcookie( ) in Example
8-1 add the Set-Cookie header field to the HTTP response. The
first encodes the start cookie with the value of the current time
as an integer returned from the time( ) function. The second encodes
the count cookie with the value of the variable
$count. Both cookies are set with the expiry date of the current
time plus 600 seconds; that is, 10 minutes. With the path parameter
set to /, the browser includes the cookies with all requests to
the site. By passing an empty string for the domain, the browser includes the
cookies only with requests to the domain of the machine serving this page. The
final parameter 0 allows the browser to transmit the cookies over
both secure and insecure connections.
Cookies can be used for simple applications that don't require complex data
to be kept between requests. However, there is a limit on the number and size
of cookies that can be set: a browser can keep only the last 20 cookies sent
from a particular domain, and the values that a cookie can hold are limited to
4 KB in size. Also, there are arguments about both the privacy and the
security of applications that use cookies, and users often disable cookie
support in their browsers. We discuss some of the security issues of cookies
in Chapter 9.
Web Database Applications with PHP & MySQL
Web Database Applications with PHP & MySQL
Session Management Over the Web - Page 3
|