10.5 PHP Session API and Configuration
This section describes
the PHP Session Management API and Configuration parameters. We also
discuss how to configure PHP to use sessions without cookies, and how
PHP garbage collection removes old unused session files.
10.5.1 Functions for Accessing Sessions in PHP
In this section we list
the key functions used to build session-based applications in PHP. By
accessing session variables using the $_SESSION
array, you can write complete session-based applications using just
four functions:
- Boolean session_start( )
-
Creates a new session, or finds an existing one. Checks for a session
ID in the HTTP request—either as a cookie or a
GET variable named PHPSESSID.
If a session ID 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 using the
session ID 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 session ID of an initialized
session or 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_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.
- void session_readonly( )
-
Initializes an existing session in read-only mode. This allows
session variables to be read without PHP placing a write lock on the
session store. This can improve performance if you expect
simultaneous requests on the session; such is the case when a browser
loads a HTML frame set and makes a parallel request for the framed
pages.
10.5.1.1 Functions used when register_globals is enabled
PHP provides several functions that
register variables in your code as session variables. Once
registered, the values of these variables are tracked and
automatically updated in the session store. However, as we have
already shown, session variables can be set and accessed using the
global array $_SESSION, and these functions need
not be used. Also these functions should not be used if
register_globals is disabled. We include a
description of these functions because you are likely to find them
used in older code:
- 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. Once a
variable is registered, it becomes available to any script that
identifies that session. Registering variables with this function
calls the session_start( ) code internally if a
session has not been initialized. Returns true if
registration is successful and false otherwise.
- Boolean session_is_registered(string
variable_name)
-
Returns true if the variable
variable_name has been registered with the
current session and false otherwise. Older code
would use this function to test if a variable is registered to
determine if a script has created a new session or initialized an
existing one.
- Boolean session_unregister(string
variable_name)
-
Unregisters the variable variable_name
from 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(
). Returns true when the variable is
unregistered and false otherwise.
- void 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.
10.5.2 Session Management Without Cookies
While cookies are used in a large
number of web sites around the world—including popular sites
such as Amazon and Google—you may need to build session-based
applications that don't rely on them. This section
shows how your application code can pass the session ID encoded in
the URL and avoid the need to set a cookie. We also discuss turning
off cookies altogether. To begin, we look at what happens when cookie
support is turned off.
10.5.2.1 No cookie?
A simple experiment that illustrates what happens when a user
disables cookies is to request the script shown in Example 10-1 from a browser that has cookie support turned
off. When repeated requests are made, the counter
doesn't increment, and the session duration remains
at zero seconds. Because a cookie isn't sent from
the browser, PHP never looks for an existing session, but creates a
new session each time the script is run. Some users configure their
browsers to not accept cookies, so session-based applications should
include an alternative communication mechanism.
Requests that don't contain the cookie can identify
an existing session by setting the value of the session ID as a
variable in the URL with the name PHPSESSID. For
example, an initial request can be made to Example 10-1 with the URL:
http://localhost/example.10-1.php
This creates a session and its associated file.
Subsequent requests can be made that include the
PHPSESSID in the URL as shown
(we've truncated the session ID to fit on the page):
http://localhost/example.10-1.php?PHPSESSID=be20081806199800da22e24...
The response shows the counter set to 2 and the correct session
duration. Repeated requests to this URL behave as expected: the
counter increments, and the calculated duration increases.
If you write session-based applications to use the URL to identify
sessions, the application doesn't fail for users who
disable cookies. Applications can test if
$_COOKIE["PHPSESSID"] is set and
then start encoding the session ID in URLs, or just not use cookies
at all.
Some browsers, such as Netscape, Mozilla, and Internet Explorer,
share cookies across all windows or tabs that are running for the
same user on the same machine. Because the cookies are shared, users
cannot log into a web database application more than once and have
independent sessions. If the session ID is stored in the URL, then
this problem is solved.
There are some security issues with having the session ID encoded in
the URL: session IDs can be stored in log files and bookmarks, and
sessions can be shared amongst users. For example, if a users wants
to share a session with another user, he can log in to the site and
email the session URL to a friend who then has access to the session.
10.5.2.2 Including the session ID in URLs
Scripts that generate embedded links to pages that use session
variables need to include a GET attribute named
PHPSESSID in the URL. This can be done using the
basic PHP string support and calls to session_id(
). For example:
<?php
// Initialize the session
session_start( );
// Generate the embedded URL to link to
// a page that processes an order
$orderUrl = "/order.php?PHPSESSID=" . session_id( );
?>
<a href="<?php print $orderUrl ?>">Create Order</a>
To aid the creation of URLs that link to session-based scripts, PHP
sets the constant SID to the session ID in a
name=id format suitable to use as a URL query
string. If no session has been initialized, PHP sets the value of
SID to be a blank string. If a session is
initialized, it sets the SID to a string
containing the session ID in the form:
PHPSESSID=be20081806199800da22e24081964000
By including the value of SID when URLs are
constructed, the hypertext links correctly identify the session. A
link that points to a script that expects a session ID can be encoded
like this:
<?php
// Initialize the session
session_start( );
?>
<a href="/order.php?<?php print SID;?>">Create Order</a>
10.5.2.3 URL rewriting
As an alternative to writing code to formulate the session ID into
the URL, PHP includes a URL rewrite feature that
automatically modifies URLs embedded in HTML.
To activate this feature you need to set the parameter
session.use_trans_sid in the
php.ini file to 1. To
activate the URL rewrite feature prior to PHP 4.2, the PHP source
also needs to be configured with the
—enable-trans-id directive and then
recompiled.
After URL rewrite is activated, PHP parses the HTML generated by
scripts and automatically alters embedded URLs to include the
PHPSESSID query string. PHP allows you to specify
which URLs to be rewritten in the
url_rewriter.tags parameter in the
php.ini file.
The URL rewrite feature has the disadvantage that extra processing is
required to parse every page generated by a PHP script, and modify
embedded URLs.
10.5.2.4 Turning off cookies
PHP session management can be instructed not to set the
PHPSESSID cookie by changing the
session.use_cookies parameter to
0 in the php.ini file. The
session configuration parameters in the php.ini
file are described later in this section.
10.5.3 Garbage Collection
While it is good practice to build
applications that provide a way to end a session— such as with
a logout script that makes a call to session_destroy(
)—there is no guarantee that a user will log out by
requesting the appropriate PHP script. PHP session management has a
built-in garbage collection mechanism that ensures unused session
files are eventually cleaned up. This is important for two reasons:
it prevents the directory from filling up with session files that can
cause performance to degrade and, more importantly, it reduces the
risk of someone guessing session IDs (more on this later) and
hijacking an old unused session.
There are three parameters that control garbage collection:
session.gc_maxlifetime,
session.gc_probability, and
session.gc_dividend, all defined in the
php.ini file. A garbage collection process is
run when a session is initialized, for example, when
session_start( ) is called. The garbage
collection process examines each session, and any sessions that have
not been accessed for a specified period of time are removed. This
period is specified as seconds of inactivity in the
gc_maxlifetime parameter; the default value is
1,440 seconds, which is 24 minutes. The file-based session management
uses the last access time of the file to determine if a session is to
be destroyed.
|
If you are running PHP on
Microsoft Windows
and storing session files on a FAT file system, the last access time
is not recorded when session variables are read. If a session is
actively being read, but not updated for a period of
gc_maxlifetime seconds, garbage collection may
remove the session incorrectly. You can write your own session
handlers to define when garbage collection removes old sessions.
Appendix F shows how to write your own session handlers.
|
|
The garbage collection process can become expensive to run,
especially in sites with high numbers of users, because the last
accessed time of every session file must be examined. The parameters
gc_probability and gc_dividend
set the percentage probability that the garbage collection process
will check for timed-out sessions. If
gc_probability is set to 1 and
gc_dividend is set to 100—the default
settings—garbage collection occurs with a probability of 1 in
100. Setting
gc_probability to 100 ensures that sessions are
examined for garbage collection with every session initialization.
Depending on the requirements, some figure between these two extremes
balances the needs of the application and performance. Unless a site
is receiving less than 1,000 hits per day, you should set the
probability quite low. For example, an application that receives
1,000 hits in a 10-hour period with a probability set to 10%, runs
the garbage collection function, on average, once every 6 minutes.
Setting the probability of running the garbage collection too high
adds unnecessary processing load on the server.
Prior to PHP 4.3 probability was simply the value of
gc_probability as a percentage; a value of 12
represented a 12% probability. The gc_dividend
parameter allows probabilities to be set below 1%, which is useful
for heavily loaded sites.
10.5.4 Configuration Parameters
Several
parameters can be manipulated to change the behavior of the PHP
session management. These parameters are set in the
php.ini
file under the heading
[Session].
- session.save_handler
-
This parameter specifies the method used by PHP to store and retrieve
session variables. The default value is files, to
indicate the use of session files as described in the previous
sections. The other values that this parameter can have are:
mm to store and retrieve variables from shared
memory, and user to store and retrieve variables
with user-defined handlers. In Appendix F we show you how to create
your own handlers to store session variables in a MySQL database. We
don't recommend using the mm
shared memory approach, as locking isn't correctly
implemented to avoid the transaction problems discussed in Chapter 8.
- session.save_path
-
This parameter specifies the directory in which session files are
saved when the session.save_handler is set to
files. The default value is the temporary
directory, /tmp. On Unix systems, you may want to
use a directory only accessible to the owner of the Apache process to
prevent other users reading session files. For Microsoft Windows
systems, you will need to change this to an appropriate path. The
specified directory must exist.
As of PHP 4.0.1, you can modify the save path to store session files
in deeper level sub-directories. This can improving efficiency for
operating systems that don't perform well with large
numbers of session files in a single directory. We
don't discuss this in detail.
- session.use_cookies
-
This parameter determines if PHP sets a cookie to hold the session
ID. Setting this parameter to 0 stops PHP from
setting cookies and may be considered for the reasons discussed in
the previous section. The default value is 1,
meaning that a cookie stores the session ID.
- session.only_use_cookies
-
When this parameter is set to 1 PHP is prevented
from overwriting the session ID set from a cookie with the value from
URL, thereby improving the security of an application. This parameter
was introduced in PHP 4.3 and has a default value of
0, which is also the default behavior in earlier
versions of PHP. However, if you use this parameter and cookies are
not enabled in sessions or in a user's browser, then
sessions will not be able to be used.
- session.name
-
This parameter controls the name of the cookie,
GET attribute, or POST
attribute that is used to hold the session ID. The default is
PHPSESSID, and there is no reason to change this
setting unless there is a name collision with another variable.
- session.auto_start
-
With the default value of 0 for this setting, PHP
initializes a session only when a session call such as
session_start( ) or session_register(
) is made. If this parameter is set to
1, sessions are automatically initialized if a
session ID is found in the request. Allowing sessions to autostart
adds unnecessary overhead if session values aren't
required for all scripts.
- session.cookie_lifetime
-
This parameter holds the life of a session cookie in seconds and is
used by PHP when setting the expiration date and time of a cookie.
The default value of 0 sets up a session cookie
that lasts only while the browser program is running. When a user
quits their browser, their session is destroyed (and the user is
logged out of the application).
Setting this value to a number of seconds other than
0 sets up the cookie with an expiration date and
time. The expiration date and time of the cookie is set as an
absolute date and time, calculated by adding the
cookie_lifetime value to the current date and time
on the server machine.
- session.cookie_path
-
This parameter sets the valid path for a cookie. The default value is
/, which means that browsers include the session
cookie in requests for resources in all paths for the
cookie's domain. Setting this value to the path of
the session-based scripts can reduce the number of requests that need
to include the cookie. For example, setting the parameter to
/winestore on a server hosting the www.webdatabasebook.com domain instructs the
browser to include the session cookie only with requests that start
with http://www.webdatabasebook.com/winestore/.
- session.cookie_domain
-
This parameter can override the domain for which the cookie is valid.
The default is a blank string, meaning that the cookie is set with
the domain of the machine running the web server, and the browser
includes the cookie only in requests sent to that domain.
- session.cookie_secure
-
This parameter sets the secure flag of a cookie, which prevents a
browser from sending the session cookie over non-encrypted
connections. When this setting is 1, the browser
sends the session cookie only over a network connection that is
protected using the Secure Sockets Layer, SSL. Setting this parameter
to 1 only makes sense when you have configured
your Web server to use SSL. We discuss SSL in the next chapter and
show how to install and configure Apache with SSL for Unix platforms
in Appendix A-Appendix C. The default value of 0 allows a
browser to send the session cookie over encrypted and non-encrypted
services. This parameter was added in PHP 4.0.4.
- session.serialize_handler
-
This parameter sets up the method by which variables are serialized,
that is, how they are converted into a stream of bytes suitable for
the chosen session store. The default value is
php, which indicates use of the standard PHP
serialization functions. An alternative is wddx,
which uses the WDDX libraries that encode variables as XML; the
library is described in Appendix G.
- session.gc_probability and session.gc_dividend
-
The probability that the garbage collection process will be performed
when a session is initialized is the value of
gc_probability divided by the value of
gc_dividend. The default values of
1 and 100 result in a 1% chance
of garbage collection each time the collector runs. See the
discussion in the previous section for a full explanation of garbage
collection.
- session.gc_maxlifetime
-
This parameter sets the life of a session in number of seconds. The
default value is 1440, or 24 minutes. Garbage
collection destroys a session that has been inactive for this period.
See the discussion in the previous section for a full explanation of
garbage collection.
- session.referer_check
-
This parameter can restrict the creation of sessions to requests that
have the HTTP Referer header field set. This is a
useful feature if access to an application is allowed only by
following a hypertext link from a particular page, such as a welcome
page. If the HTTP Referer header of a request that
is external to the host doesn't contain the value of
this parameter, PHP creates a session, but the session is marked as
invalid and unusable. Subsequent requests will fail to initialize
session variables from the session. The default value of a blank
string applies no restriction.
- session.entropy_file
-
PHP generates the session IDs from a random number seeded by the
system date and time. Because the algorithm is known—it can be
looked up in the PHP source code—it makes guessing session IDs
a little easier. If this parameter is set to the name of a file, the
first n bytes from that file (where
n is specified by the
session.entropy_length parameter) are used to seed
the random number generator, making the ID less predictable. The
default value is left blank, meaning the default seeding method is
used. On Unix systems, an alternative is to use
/dev/urandom, a special Unix device that
produces a pseudo-random number.
- session.entropy_length
-
This parameter is the number of bytes to use when generating a
session ID from the file specified by
session.entropy_file. The default value of
0 is required when no entropy file is set.
- session.cache_limiter
-
This parameter controls how clients and proxy servers cache
responses. Web applications—and especially session-based web
applications—can be adversely affected when pages are cached.
The default value of nocache prevents caching in
both clients and proxy servers. Setting this parameter to
public allows caching in both clients and proxy
servers, while the value of private allow caching
in the client only. PHP 4.2 allows the value
private_no_expire in this parameter, which avoids
problems in some browsers when the Expire header
field is used to control caching. See Appendix D for more details
about HTTP caching.
- session.cache_expire
-
This parameter is used when caching is allowed; it sets the
expiration date and time of the response to be the current system
time plus the parameter value in minutes. The default value is
180.
- session.bug_compat_42 and session.bug_compat_warn
-
Prior to PHP 4.2, session variables could be initialized in the
global scope, even when register_globals was
disabled. While this is considered a bug, PHP allows code written
with this behavior to run with bug_compat_42 set
to 1 and provides warnings with
bug_compat_warn set to 1 (the
default values). Setting these parameters to 0
turns off compatibility and warnings respectively. If you are writing
new code, we recommend that bug_compat_42 is set
to 0.
|