downloads | documentation | faq | getting help | mailing lists | reporting bugs | sites | links | my 
search for in the  
view the version of this page
Last updated: Thu, 21 Aug 2003

XCIV. Session handling functions


Session support in PHP consists of a way to preserve certain data across subsequent accesses. This enables you to build more customized applications and increase the appeal of your web site.

A visitor accessing your web site is assigned an unique id, the so-called session id. This is either stored in a cookie on the user side or is propagated in the URL.

The session support allows you to register arbitrary numbers of variables to be preserved across requests. When a visitor accesses your site, PHP will check automatically (if session.auto_start is set to 1) or on your request (explicitly through session_start() or implicitly through session_register()) whether a specific session id has been sent with the request. If this is the case, the prior saved environment is recreated.


If you do turn on session.auto_start then you cannot put objects into your sessions since the class definition has to be loaded before starting the session in order to recreate the objects in your session.

All registered variables are serialized after the request finishes. Registered variables which are undefined are marked as being not defined. On subsequent accesses, these are not defined by the session module unless the user defines them later.

Note: Session handling was added in PHP 4.0.

Note: Please note when working with sessions that a record of a session is not created until a variable has been registered using the session_register() function or by adding a new key to the $_SESSION superglobal array. This holds true regardless of if a session has been started using the session_start() function.

Sessions and security

External links: Session fixation

The session module cannot guarantee that the information you store in a session is only viewed by the user who created the session. You need to take additional measures to actively protect the integrity of the session, depending on the value associated with it.

Assess the importance of the data carried by your sessions and deploy additional protections -- this usually comes at a price, reduced convenience for the user. For example, if you want to protect users from simple social engineering tactics, you need to enable session.use_only_cookies. In that case, cookies must be enabled unconditionally on the user side, or sessions will not work.

There are several ways to leak an existing session id to third parties. A leaked session id enables the third party to access all resources which are associated with a specific id. First, URLs carrying session ids. If you link to an external site, the URL including the session id might be stored in the external site's referrer logs. Second, a more active attacker might listen to your network traffic. If it is not encrypted, session ids will flow in plain text over the network. The solution here is to implement SSL on your server and make it mandatory for users.


No external libraries are needed to build this extension.

Note: Optionally you can use shared memory allocation (mm), developed by Ralf S. Engelschall, for session storage. You have to download mm and install it. This option is not available for Windows platforms. Note that the session storage module for mm does not guarantee that concurrent accesses to the same session are properly locked. It might be more appropiate to use a shared memory based filesystem (such as tmpfs on Solaris/Linux, or /dev/md on BSD) to store sessions in files, because they are properly locked.


Session support is enabled in PHP by default. If you would not like to build your PHP with session support, you should specify the --disable-session option to configure. To use shared memory allocation (mm) for session storage configure PHP --with-mm[=DIR] .

The windows version of PHP has built in support for this extension. You do not need to load any additional extension in order to use these functions.

Note: By default, all data related to a particular session will be stored in a file in the directory specified by the session.save_path INI option. A file for each session (regardless of if any data is associated with that session) will be created. This is due to the fact that a session is opened (a file is created) but no data is even written to that file. Note that this behavior is a side-effect of the limitations of working with the file system and it is possible that a custom session handler (such as one which uses a database) does not keep track of sessions which store no data.

Runtime Configuration

The behaviour of these functions is affected by settings in php.ini.

Table 1. Session configuration options

session.use_trans_sid"0"PHP_INI_SYSTEM | PHP_INI_PERDIR
For further details and definition of the PHP_INI_* constants see ini_set().

The session management system supports a number of configuration options which you can place in your php.ini file. We will give a short overview.

session.save_handler string

session.save_handler defines the name of the handler which is used for storing and retrieving data associated with a session. Defaults to files. See also session_set_save_handler().

session.save_path string

session.save_path defines the argument which is passed to the save handler. If you choose the default files handler, this is the path where the files are created. Defaults to /tmp. See also session_save_path().

There is an optional N argument to this directive that determines the number of directory levels your session files will be spread around in. For example, setting to '5;/tmp' may end up creating a session file and location like /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If . In order to use N you must create all of these directories before use. A small shell script exists in ext/session to do this, it's called Also note that if N is used and greater than 0 then automatic garbage collection will not be performed, see a copy of php.ini for further information. Also, if you use N, be sure to surround session.save_path in "quotes" because the separator (;) is also used for comments in php.ini.


If you leave this set to a world-readable directory, such as /tmp (the default), other users on the server may be able to hijack sessions by getting the list of files in that directory.

Note: Windows users have to change this variable in order to use PHP's session functions. Make sure to specify a valid path, e.g.: c:/temp. string specifies the name of the session which is used as cookie name. It should only contain alphanumeric characters. Defaults to PHPSESSID. See also session_name().

session.auto_start boolean

session.auto_start specifies whether the session module starts a session automatically on request startup. Defaults to 0 (disabled).

session.serialize_handler string

session.serialize_handler defines the name of the handler which is used to serialize/deserialize data. Currently, a PHP internal format (name php) and WDDX is supported (name wddx). WDDX is only available, if PHP is compiled with WDDX support. Defaults to php.

session.gc_probability integer

session.gc_probability specifies the probability that the gc (garbage collection) routine is started on each request in percent. Defaults to 1.

session.gc_maxlifetime integer

session.gc_maxlifetime specifies the number of seconds after which data will be seen as 'garbage' and cleaned up.

Note: If you are using the default file-based session handler, your filesystem must keep track of access times (atime). Windows FAT does not so you will have to come up with another way to handle garbage collecting your session if you are stuck with a FAT filesystem or any other fs where atime tracking is not available.

session.referer_check string

session.referer_check contains the substring you want to check each HTTP Referer for. If the Referer was sent by the client and the substring was not found, the embedded session id will be marked as invalid. Defaults to the empty string.

session.entropy_file string

session.entropy_file gives a path to an external resource (file) which will be used as an additional entropy source in the session id creation process. Examples are /dev/random or /dev/urandom which are available on many Unix systems.

session.entropy_length integer

session.entropy_length specifies the number of bytes which will be read from the file specified above. Defaults to 0 (disabled).

session.use_cookies boolean

session.use_cookies specifies whether the module will use cookies to store the session id on the client side. Defaults to 1 (enabled).

session.use_only_cookies boolean

session.use_only_cookies specifies whether the module will only use cookies to store the session id on the client side. Defaults to 0 (disabled, for backward compatibility). Enabling this setting prevents attacks involved passing session ids in URLs. This setting was added in PHP 4.3.0.

session.cookie_lifetime integer

session.cookie_lifetime specifies the lifetime of the cookie in seconds which is sent to the browser. The value 0 means "until the browser is closed." Defaults to 0.See also session_get_cookie_params() and session_set_cookie_params().

session.cookie_path string

session.cookie_path specifies path to set in session_cookie. Defaults to /.See also session_get_cookie_params() and session_set_cookie_params().

session.cookie_domain string

session.cookie_domain specifies the domain to set in session_cookie. Default is none at all. See also session_get_cookie_params() and session_set_cookie_params().

session.cookie_secure boolean

session.cookie_secure specifies whether cookies should only be sent over secure connections. Defaults to off. This setting was added in PHP 4.0.4. See also session_get_cookie_params() and session_set_cookie_params().

session.cache_limiter string

session.cache_limiter specifies cache control method to use for session pages (none/nocache/private/private_no_expire/public). Defaults to nocache. See also session_cache_limiter().

session.cache_expire integer

session.cache_expire specifies time-to-live for cached session pages in minutes, this has no effect for nocache limiter. Defaults to 180. See also session_cache_expire().

session.use_trans_sid boolean

session.use_trans_sid whether transparent sid support is enabled or not. Defaults to 0 (disabled).

Note: For PHP 4.1.2 or less, it is enabled by compiling with --enable-trans-sid. From PHP 4.2.0, trans-sid feature is always compiled.

URL based session management has additional security risks compared to cookie based session management. Users may send an URL that contains an active session ID to their friends by email or users may save an URL that contains a session ID to their bookmarks and access your site with the same session ID always, for example.

session.bug_compat_42 boolean

PHP versions 4.2.0 and lower have an undocumented feature/bug that allows you to to initialize a session variable in the global scope, albeit register_globals is disabled. PHP 4.3.0 and later will warn you, if this feature is used, and if session.bug_compat_warn is also enabled.

session.bug_compat_warn boolean

PHP versions 4.2.0 and lower have an undocumented feature/bug that allows you to to initialize a session variable in the global scope, albeit register_globals is disabled. PHP 4.3.0 and later will warn you, if this feature is used by enabling both session.bug_compat_42 and session.bug_compat_warn.

url_rewriter.tags string

url_rewriter.tags specifies which html tags are rewritten to include session id if transparent sid support is enabled. Defaults to a=href,area=href,frame=src,input=src,form=fakeentry,fieldset=

Note: If you want XHTML conformity, remove the form entry and use the <fieldset> tags around your form fields.

The track_vars and register_globals configuration settings influence how the session variables get stored and restored.

Note: As of PHP 4.0.3, track_vars is always turned on.

Resource Types

This extension has no resource types defined.

Predefined Constants

The constants below are defined by this extension, and will only be available when the extension has either been compiled into PHP or dynamically loaded at runtime.

SID (string)

Constant containing the session name and session ID in the form of "name=ID".


Note: As of PHP 4.1.0, $_SESSION is available as a global variable just like $_POST, $_GET, $_REQUEST and so on. Unlike $HTTP_SESSION_VARS, $_SESSION is always global. Therefore, you do not need to use the global keyword for $_SESSION. Please note that this documentation has been changed to use $_SESSION everywhere. You can substitute $HTTP_SESSION_VARS for $_SESSION, if you prefer the former. Also note that you must start your session using session_start() before use of $_SESSION becomes available.

The keys in the $_SESSION associative array are subject to the same limitations as regular variable names in PHP, i.e. they cannot start with a number and must start with a letter or underscore. For more details see the section on variables in this manual.

If register_globals is disabled, only members of the global associative array $_SESSION can be registered as session variables. The restored session variables will only be available in the array $_SESSION.

Use of $_SESSION (or $HTTP_SESSION_VARS with PHP 4.0.6 or less) is recommended for improved security and code readablity. With $_SESSION, there is no need to use the session_register(), session_unregister(), session_is_registered() functions. Session variables are accessible like any other variables.

Example 1. Registering a variable with $_SESSION.

// Use $HTTP_SESSION_VARS with PHP 4.0.6 or less
if (!isset($_SESSION['count'])) {
    $_SESSION['count'] = 0;
} else {

Example 2. Unregistering a variable with $_SESSION and register_globals disabled.

// Use $HTTP_SESSION_VARS with PHP 4.0.6 or less


Do NOT unset the whole $_SESSION with unset($_SESSION) as this will disable the registering of session variables through the $_SESSION superglobal.

Example 3. Unregistering a variable with register_globals enabled, after registering it using $_SESSION.

// With PHP 4.3 and later, you can also simply use the prior example.

If register_globals is enabled, then each global variable can be registered as session variable. Upon a restart of a session, these variables will be restored to corresponding global variables. Since PHP must know which global variables are registered as session variables, users need to register variables with session_register() function. You can avoid this by simply setting entries in $_SESSION.


If you are using $_SESSION and disable register_globals, do not use session_register(), session_is_registered() and session_unregister(), if your scripts shall work in PHP 4.2 and earlier. You can use these functions in 4.3 and later.

If you enable register_globals, session_unregister() should be used since session variables are registered as global variables when session data is deserialized. Disabling register_globals is recommended for both security and performance reasons.

Example 4. Registering a variable with register_globals enabled

if (! isset($_SESSION['count'])) {
    $_SESSION['count'] = 1;
else {

If register_globals is enabled, then the global variables and the $_SESSION entries will automatically reference the same values which were registered in the prior session instance.

There is a defect in PHP 4.2.3 and earlier. If you register a new session variable by using session_register(), the entry in the global scope and the $_SESSION entry will not reference the same value until the next session_start(). I.e. a modification to the newly registered global variable will not be reflected by the $_SESSION entry. This has been corrected in PHP 4.3.

Passing the Session ID

There are two methods to propagate a session id:

  • Cookies

  • URL parameter

The session module supports both methods. Cookies are optimal, but because they are not always available, we also provide an alternative way. The second method embeds the session id directly into URLs.

PHP is capable of transforming links transparently. Unless you are using PHP 4.2 or later, you need to enable it manually when building PHP. Under UNIX, pass --enable-trans-sid to configure. If this build option and the run-time option session.use_trans_sid are enabled, relative URIs will be changed to contain the session id automatically.

Note: The arg_separator.output php.ini directive allows to customize the argument seperator. For full XHTML conformance, specify &amp; there.

Alternatively, you can use the constant SID which is always defined. If the client did not send an appropriate session cookie, it has the form session_name=session_id. Otherwise, it expands to an empty string. Thus, you can embed it unconditionally into URLs.

The following example demonstrates how to register a variable, and how to link correctly to another page using SID.

Example 5. Counting the number of hits of a single user

if (!session_is_registered('count')) {
    $count = 1;
else {

Hello visitor, you have seen this page <?php echo $count; ?> times.<p>

To continue, <A HREF="nextpage.php?<?php echo strip_tags (SID)?>">click here</A>

The strip_tags() is used when printing the SID in order to prevent XSS related attacks.

Printing the SID, like shown above, is not necessary if --enable-trans-sid was used to compile PHP.

Note: Non-relative URLs are assumed to point to external sites and hence don't append the SID, as it would be a security risk to leak the SID to a different server.

Custom Session Handlers

To implement database storage, or any other storage method, you will need to use session_set_save_handler() to create a set of user-level storage functions.

Table of Contents
session_cache_expire -- Return current cache expire
session_cache_limiter -- Get and/or set the current cache limiter
session_decode -- Decodes session data from a string
session_destroy -- Destroys all data registered to a session
session_encode --  Encodes the current session data as a string
session_get_cookie_params --  Get the session cookie parameters
session_id -- Get and/or set the current session id
session_is_registered --  Find out whether a global variable is registered in a session
session_module_name -- Get and/or set the current session module
session_name -- Get and/or set the current session name
session_regenerate_id --  Update the current session id with a newly generated one
session_register --  Register one or more global variables with the current session
session_save_path -- Get and/or set the current session save path
session_set_cookie_params --  Set the session cookie parameters
session_set_save_handler --  Sets user-level session storage functions
session_start -- Initialize session data
session_unregister --  Unregister a global variable from the current session
session_unset --  Free all session variables
session_write_close -- Write session data and end session

add a note add a note User Contributed Notes
Session handling functions
zombie (at) localm (dotto) oh - arr-gee
10-Aug-2003 06:42
I don't know if this is obvious or not, but since it took me forever to figure it out, i will post it...

// If you want to share cookie/session info with a domain name and it's subdomains/Cnames,
// the only thing you really should have to do is:


//see what we have in our session...


This will allow cookies/session info to be available to as well as its Cnames (ex:,,

All this does is set the domain attribute of the set_cookie() style function sessions use since a "session" is just a cookie on your computer that php looks for that contains your session id.

I assume, therefor that you can do something of the like for cookies in javascript and such.

The silly thing about all this is that it is a "feature" of cookies to be able to span c names/subdomains. This is exactly why set_cookie() has an option domain argument. However, it seems like most of the people have had my problem have not gone in that direction or at least not posted a correct solution on the web. Google just gave me lots of hacked solutions. In my quest, i read articles about apache hacks, setting the serverside session storage folder, using file() from a sub on a file doing a print_r on the session located ont he main server, etc etc. I guess if you really know how cookies work (which i thought i did before all this mess but obviously not) then this problem seems like not much of a problem at all and a simple missunderstanding of what cookies do and why they are cool.

Wizards vs Hackers.

I hope this helps someone.

webmaster of the art attack
orion at dr-alliance dot com
09-Aug-2003 05:52
Session ID's wont be carried over through meta refreshes, so make sure you add the variables (in GET format) to the URL.
IE )
<meta http-equiv=\"refresh\" content=\"1;URL=index.php?PHPSESSID=$PHPSESSID\">
quinn at strangecode dot com
20-Mar-2003 06:10
Do not 'global' a superglobal! If you register a $_SUPERGLOBAL as a global variable (as in...  global $_SESSION; within a function definition) strange things happen with some versions of PHP (PHP 4.2.3 on my MacOS X powerbook, but not my PHP 4.2.3 RH 7.3 linux machine). In the case I found, $_SESSION and $HTTP_SESSION_VARS would not reference the same data, and unsetting or accessing the data was inconsistant. Didn't test very far, but obviously this should not be done, and it did wreck havoc for me.
tim at digicol dot de
05-Feb-2003 02:14
Be careful when using ini_set to change the  session.gc_maxlifetime value locally for your script:

You will trash other people's sessions when garbage collection takes place (and they will trash yours) regardless of their (your) intended session.gc_maxlifetime, because the session_name is not taken into account during garbage collection.

Create an own directory and set session.save_path to it, so that your session files don't get mixed.
nutbar at innocent dot com
18-Jan-2003 06:44
Someone posted a message here saying you should just all use the MM shared memory management for sessions.  I'd like to CAUTION EVERYONE against using it!

I run a few webservers for a webhosting company, and we quickly ran in to PHP pages segfaulting Apache for unknown reasons, until we did a test with sessions.  It turns out that the sessions, while using the mm stuff, couldn't keep the data right.  I guess it was to do with the file locking issue mentioned in the documentation here (I didn't notice this until now!).

Anyways, if you run a Unix machine that can map virtual memory to a mount point (like tmpfs or shm or whatever it may be called), use this instead.  It's volatile like mm, but works.  Only thing you don't get is hidden session info so that other people don't know how to open it easily - but it's better than trying to use mm and having the webserver crash all the time!
jules at dsf dot org dot uk
17-Jan-2003 05:13
There are a few comments above about how using sessions might not be secure, but quite apart from session hijacking, there is a mistake that I think a lot of people are making at the moment that everyone needs to stop and make sure they aren't one.

This mistake arises from having the 'register_globals' setting on.

Take the following example code which is meant to maintain a session variable for whether a user is logged in and allow them to log in using a username and password if they aren't logged in, or give an option for logging out if they are:

  if (!
strcmp($user"user") && !strcmp($pass"password"))
$logged_in 1;

  if (
$logged_in 0;

  if (
"logged in. <A href=\"sestest.php?logout=1\">log out</A>";
"<FORM action=sestest.php method=get>User: <INPUT type=text name=user><BR>Password: <INPUT type=text name=pass><BR><INPUT type=submit></FORM>";

This works fine under normal use, but an attacker can log in without knowing the username or password by accessing '.../sestest.php?logged_in=1', which will set the session variable 'logged_in' to the value 1.

However, once a session variable has been set, it cannot be overridden in this fashion, so one solution is to use code like the code shown above (which has no explanation attached as to why you should do it that way) that uses session_is_registered:

  if (!
session_is_registered ("logged_in"))
$logged_in 0;
session_register ("logged_in");
mark6139 at yahoo dot com
26-Dec-2002 03:54
As a more general follow-up to Ryan's note from 11/23, just don't use any local variables with the same name as a member of the $_SESSION array.  Doing so for me messed things up even in the simplest case (where I did not unset the session array member).
thebitman at attbi dot com
16-Dec-2002 04:01
[Editor's Note] Locking a session to an IP address will sometimes result in valid user's sessions not being restored.  ISPS sometimes use more than one proxy server, the ISP may direct the traffic through a different proxy on each request[/Note]

The easiest (and therefor, most vulnerable) method of validating a session is to just keep a copy of the REMOTE_IP in $_SESSION, and compare it at the beginning of your script. Of course this doesnt prevent someone from blindly sending things to your server and getting no reply, but I think it will do a pretty good job of preventing someone from hijacking your session in order to get ahold of an order confirmation page that has your address and CC# on it.
As a general rule: Keep track of your users. NEVER allow POST data for things like online purchases without making sure that the last page they were on is the page that should be making that POST (and I dont mean checking the referer: header. This kind of thing is what the _SESSION variable can be good for storing)
Jester at free2code dot net
18-Nov-2002 06:50
It seems quite a lot of people have trouble understanding what sessions do and what they're good for.

For a more newbie explanation our tutorial might help you:

I tried to expplain how to use sessions in as simple terms as possible, for anyone having trouble understanding this page, give it a go.
13-Oct-2002 05:43
If you have problem to download a file from your PHP , and you have IE (any version) and apache for server with SSL, check the reference of: session-cache-limiter

My best solution is change the php.ini from

session.cache_limiter = nocache


session.cache_limiter = private, must-revalidate
15-May-2002 01:34
Storing class instances in session.

As long as a class MUST be declared BEFORE the session starts and unserializes the session info, i'm using this approach.

0: Set in php.ini session.auto_start = 0
1: create where the class is declared.
2: put in another file, say, this lines of code:
include_once( "" );
3: set in php.ini the auto_prepend_file= "path_to_my_file/"

Following this steps, the session is started at every page and myclass is always available, avoiding to write the session_start() function at every page.
stoiev at ig dot com
21-Mar-2002 01:10
Carefull when you are working in PHP with WML. The arg separator used to put de PHPSESSID variable in URL is '&' by default, and this cause a Compile Error in browsers:

<anchor><go href="index.php?estate=1&PHPSESSID=12345678abcde"></go>

instead of this:

<anchor><go href="index.php?estate=1&#38;PHPSESSID=12345678abcde"></go>

It愀 safety include the line:
ini_set ( "arg_separator", "&#38;");

to change the arg separator, it worked in PHP 4.1.2

Another thing that the onpick tag is not defined in the url_rewriter.tags list by default(if there are others, i don愒 now). This is must be added in php.ini file.

* In most case the WAP GateWay accepts cookies an the auto-transpass-SID is not necessary, it愀 hard to find problems with this.
j dot marloweNOSPAM at gmx dot NO_SPAM dot net
12-Feb-2002 06:47
for anyone in the need of a simple login script tutorial featuring sessions, try here:
j dot mccoy at cc dot utexas dot edu
04-Jun-2001 02:53
If your using PHP session handling with PostgreSQL as session storage, a efficient method of handling garbage collection would be a rule:

create rule rle_sessions_gc as on insert into sessions where (random() >= 0.7) do delete from sessions where expiry <= current_timestamp;

this rule assumes that the sessions table has an expiry field into which is placed the timestamp at which the session should expire; change the value random is checked against to change the probability of garbage collection.
j at rtchat dot com
28-Dec-2000 12:49
To get more secure session IDs, here is what I use on GNU/linux :

ini_alter("session.cookie_lifetime", "86400");
ini_alter("session.entropy_length", "512");

You can also use /dev/random instead of /dev/urandom but it's a slower.
ricmarques at spamcop dot net
16-Oct-2000 08:16
Regarding session.cache_limiter :

For those of you who - like me - had trouble finding the meaning of the possible values (nocache, public and private), here's the explaination taken from the HTTP 1.1 Specification at

"14.9.1 What is Cachable


  Indicates that the response is cachable by any cache, even if it would normally be non-cachable or cachable only within a non-shared cache. (See also Authorization, section 14.8, for additional details.)

  Indicates that all or part of the response message is intended for a  single user and MUST NOT be cached by a shared cache. This allows an origin server to state that the specified parts of the response are intended for only one user and are not a valid response for requests by other users. A private (non-shared) cache may cache the response.

  Note: This usage of the word private only controls where the response may be cached, and cannot ensure the privacy of the message content.

  Indicates that all or part of the response message MUST NOT be cached anywhere. This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.

  Note: Most HTTP/1.0 caches will not recognize or obey this directive."
shanemayer42 at yahoo dot com
20-Aug-2000 09:11
Session Garbage Collection Observation:

It appears that session file garbage collection occurs AFTER the current session is loaded. 

This means that:
even if session.gc_maxlifetime = 1 second,
if someone starts a session A and no one starts a session for an hour,  that person can reconnect to session A and all of their previous session values will be available (That is, session A will not be cleaned up even though it is older than gc_maxlifetime).

 Last updated: Thu, 21 Aug 2003
show source | credits | sitemap | mirror sites 
Copyright © 2001-2003 The PHP Group
All rights reserved.
This mirror generously provided by:
Last updated: Sat 01 Nov 2003 04:13:36 EST EST