A fundamental characteristic of the Web is the
stateless interaction between browsers and web servers. As discussed in
Chapter 1, HTTP is a stateless protocol. Each HTTP request a browser
sends to a web server is independent of any other request.
Storing the state in the web server -- the middle tier -- can solve
the problem of increased request size and protect the state of an
application from accidental or intentional changes a user might make.
A session is a way to identify and manage the state--the session variables--for
a particular user. When a user sends an HTTP request, the middle tier
must process the current request in the context of the user's session.
When a session is started, the client is given a session identifier--often
a cookie--that is included with subsequent requests to the server. The
server uses the session identifier to locate the corresponding session
before processing the request.
Rather than storing all the variables needed to maintain state and
include them with each request, the browser stores a single session
identifier that finds and initializes the variables stored on the
server. The session identifier is like the ticket given at a cloak
room. The ticket is much easier to carry around and ensures that the
holder gets her own hat and coat.
One implication of storing session variables in the middle tier is
that data needs to be stored for each session. The question is, for how
long? Because HTTP is stateless, there is no way to know when a user
has finished with a session. Ideally, the user logs out of an
application, and the logout script ends the session. However, because a
server can never be sure if a user is still there, the server needs to
clean up old sessions that have not been used for a period of time.
This last point is important, because sessions consume resources on the
server, and dormant sessions may present a security risk. How long the
timeout should be depends on the needs of the application, and we
discuss this in more detail later in this chapter.
In summary, there are three characteristics session management over the Web must exhibit:
-
Information or state must be stored. For example, a
selected bottle of wine in a shopping cart, a customer name, or a
credit card number must be maintained across multiple HTTP requests.
-
Each HTTP request must carry an identifier that allows
the server to process the request in the context of the stored state.
For example, when an order is submitted, it must be processed with the
correct items and customer details.
-
Sessions need to have a timeout. Otherwise, if a user leaves the web site, there is no way the server can tell when the session should end.
PHP Session Management
With the release of PHP4, session management was introduced as an
extension to the PHP language. PHP provides several session-related
functions, and developing applications that use PHP sessions is
straightforward. The three important features of session management are
mostly taken care of by the PHP scripting engine.
In this section, we present how to use PHP sessions, showing how
sessions are started and ended and how session variables are used. We
list the PHP functions for building session-based web applications.
Because not all browsers support cookies, and some users actively
disable them, we describe how to use PHP sessions without relying on
cookies. Finally, we show how to configure PHP session management with
a discussion on the garbage collection used to remove old sessions and
other configuration parameters.
Overview
An overview of PHP session management is shown in Figure 8-1. When a
user first enters the session-based application by making a request to
a page that starts a session, PHP generates a session ID and creates a
file that stores the session-related variables. PHP sets a cookie to
hold the session ID in the response the script generates. The browser
then records the cookie and includes it in subsequent requests. In the
example shown in Figure 8-1, the script welcome.php records session variables in the session store, and a request to next.php then has access to those variables because of the session ID.
|

Figure 8-1. The interaction between the browser and the server when initial requests are made to a session-based application
|
The out-of-the-box configuration of PHP session management uses
disk-based files to store session variables. Using files as the session
store is adequate for most applications in which the numbers of
concurrent sessions are limited. A more scalable solution that uses a
MySQL database as a session store is provided in Appendix D.
Starting a Session
PHP provides a session_start( ) function that creates a new session and subsequently identifies and establishes an existing one. Either way, a call to the session_start( ) function initializes a session.
The first time a PHP script calls session_start( ), a session identifier is generated, and, by default, a Set-Cookie header field is included in the response. The response sets up a session cookie in the browser with the name PHPSESSID
and the value of the session identifier. The PHP session management
automatically includes the cookie without the need to call to the setcookie( ) or header( ) functions.
The session identifier (ID) is a random string of 32 hexadecimal digits, such as fcc17f071bca9bf7f85ca281094390b4. As with other cookies, the value of the session ID is made available to PHP scripts in the $HTTP_COOKIE_VARS associative array and in the $PHPSESSID variable.
When a new session is started, PHP creates a session file. With the default configuration, session files are written in the /tmp directory using the session identifier, prefixed with sess_, for the filename. The filename associated with our example session ID is /tmp/sess_fcc17f071bca9bf7f85ca281094390b4.
If a call is made to session_start( ), and the request contains the PHPSESSID
cookie, PHP attempts to find the session file and initialize the
associated session variables as discussed in the next section. However,
if the identified session file can't be found, session_start( ) creates an empty session file.
Using Session Variables
Variables need to be registered with the session_register( ) function that's used in a session. If a session has not been initialized, the session_register( ) function calls session_start( ) to open the session file. Variables can be registered -- added to the session file -- with the session_register( ) call as follows:
// Register the variable named "foo"
session_register("foo");
$foo = "bar";
Note that it is the name of the variable that is passed to the session_register( )
function, not the variable itself. Once registered, session variables
are made persistent and are available to scripts that initialize the
session. PHP tracks the values of session variables and saves their
values to the session file: there is no need to explicitly save a
session variable before a script ends. In the previous example, the
variable $foo is automatically saved in the session store with its value bar.
Variables can be removed from a session with the session_unregister( )
function call; again, the name of the variable is passed as the
argument, not the variable itself. A variable that is unregistered is
no longer available to other scripts that initialize the session.
However, the variable is still available to the rest of the script
immediately after the session_unregister( ) function call.
Scripts that initialize a session have access to the session variables through the associative array $HTTP_SESSION_VARS, and PHP automatically initializes the named session variables if register_globals is enabled.
Example 8-2 shows a simple script that registers two variables: an integer $count, which is incremented each time the script is called, and $start, which is set to the current time from the library function time( ) when the session is first initialized. The script tests if the variable $count has been registered to determine if a new session has been created. If the variable $count has been registered already, the script increments its value.
Do not use the existence of $PHPSESSID as indicative of
a new session, or as a method to access the session ID. The first time
a script is called and the session is created, the PHPSESSID cookie may not be set. Only subsequent requests are guaranteed to contain the PHPSESSID cookie. PHP provides a session_id( ) function that returns the session ID for the initialized session.
The script shown in Example 8-2 displays both variables: $count shows how many times the script has been called, and time( ) - $start shows how many seconds the session has lasted.
Example 8-2: Simple PHP script that uses a session
<?php
// Initialize a session. This call either creates
// a new session or re-establishes an existing one.
session_start( );
// If this is a new session, then the variable
// $count will not be registered
if (!session_is_registered("count"))
{
session_register("count");
session_register("start");
$count = 0;
$start = time( );
}
else
{
$count++;
}
$sessionId = session_id( );
?>
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd" >
<html>
<head><title>Sessions</title></head>
<body>
<p>This page points at a session
(<?=$sessionId?>)
<br>count = <?=$count?>.
<br>start = <?=$start?>.
<p>This session has lasted
<?php
$duration = time( ) - $start;
echo "$duration";
?>
seconds.
</body>
</html>
Session variables can be of the type Boolean, integer, double,
string, object, or arrays of those variable types. Care must be taken
when using object session variables, because PHP needs access to the
class definitions of registered objects when initializing an existing
session. If objects are to be stored as session variables, you should
include class definitions for those objects in all scripts that
initialize sessions, whether the scripts use the class or not. Objects
and classes are described in Chapter 2.
PHP stores session variables in the session file by serializing
the values. The serialized representation of a variable includes the
name, the type, and the value as a stream of characters suitable for
writing to a file. Here's an example of a file that was created when
the script shown in Example 8-2 was run several times:
count|i:6;start|i:986096496;
A PHP developer need not worry how serialization occurs; PHP session
management takes care of reading and writing session variables
automatically.
Ending a Session
At some point in an application, sessions may need to be destroyed.
For example, when a user logs out of an application, a call to the session_destroy( ) function can be made. A call to session_destroy( ) removes the session file from the system but doesn't remove the PHPSESSID cookie from the browser.
Example 8-3 shows how the session_destroy( ) function is called. A session must be initialized before the session_destroy( ) call can be made. You should also test to see if $PHPSESSID
is a set variable before killing the session. This prevents the code
from creating a session, then immediately destroying it if the script
is called without identifying a session. However, if the user has
previously held a session cookie, PHP initializes the $PHPSESSID variable, and the code redundantly creates and destroys a session.
Example 8-3: Ending a session
<?php
// Only attempt to end the session if there
// is a $PHPSESSID set by the request.
if(isset($PHPSESSID)) {
$message = "<p>End of session ($PHPSESSID).";
session_start( );
session_destroy( );
} else {
$message = "<p>There was no session to destroy!";
}
?>
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd" >
<html>
<head><title>Sessions</title></head>
<body>
<?=$message?>
</body>
</html>
ions
Functions for Accessing Sessions in PHP
In this section we list the key functions used to build
session-based applications in PHP. Greater control over sessions can be
achieved through the configuration of PHP--as we discuss in the
"Configuration of PHP Session Management" section -- or by using GET variables to encode the session ID, as discussed in the next section.
- Boolean session_start( )
-
Initializes a session by either creating a new session or using an identified one. Checks for the variable $PHPSESSID
in the HTTP request. If a session identifier isn't included in the
request, or an identified session isn't found, a new session is
created. If a session ID is included in the request, and a session
isn't found, a new session is created with the PHPSESSID
encoded in the request. When an existing session is found, the session
variables are read from the session store and initialized. Using PHP's
default settings, a new session is created as a file in the /tmp directory. This function always returns true.
- string session_id([string id])
-
Can be used in two ways: to return the ID of an initialized
session and to set the value of a session ID before a session is
created. When used to return the session ID, the function must be
called without arguments after a session has been initialized. When
used to set the value of the session ID, the function must be called
with the ID as the parameter before the session has been initialized.
- Boolean session_register(mixed name [, mixed ...])
-
Registers one or more variables in the session store. Each
argument is the name of a variable, or an array of variable names, not
the variable itself. Once a variable is registered, it becomes
available to any script that identifies that session. This function
calls the session_start( ) code internally if a session has not been initialized. The session_unregister( ) function is called to remove a variable from the session. Returns true when the variables are successfully registered.
- Boolean session_is_registered(string variable_name)
-
Returns true if the named variable has been registered with the current session and false
otherwise. Using this function to test if a variable is registered is a
useful way to determine if a script has created a new session or
initialized an existing one.
- session_unregister(string variable_name)
-
Unregisters a variable with the initialized session. Like the session_register( ) function, the argument is the name of the variable, not the variable itself. Unlike the session_register( )
function, the session needs to be initialized before calling this
function. Once a variable has been removed from a session with this
call, it is no longer available to other scripts that initialize the
session. However, the variable is still available to the rest of the
script that calls session_unregister( ).
- session_unset( )
-
Unsets the values of all session variables. This function doesn't unregister the actual session variables. A call to session_is_registered( ) still returns true for the session variables that have been unset.
- Boolean session_destroy( )
- Removes the session from the PHP session management. With PHP's
default settings, a call to this function removes the session file from
the /tmp directory. Returns true if the session is successfully destroyed and false otherwise.
|