10) Advanced PHP Sessions

Advanced PHP Sessions

Sessions Need Cookies on Client End: In PHP, by default session data is stored in files on the server. Each file is named after a cookie that is stored on the client computer. This session cookie (PHPSESSID) presumably survives on the client side until all windows of the browser are closed. If the file on either end is deleted (server or client) the session is deemed not to be a match, and the session is invalid. Nearly all cookie management systems require the use of cookies on the client end. However, the handling on the server end of the session can vary.

 Session Handling Mechanisms on Server End: Almost all technologies provide the mechanism to store sessions in various ways. The default mechanism in PHP is to store sessions in the file system. This provides the advantage of simple file based storage and the ability for sessions to exist for long periods of time (sometimes too long!). In Microsoft products (ASP, ASP.NET) the default mechanism is server memory, which is operationally faster to access but much more precious. Therefore, instead of sessions that last too long (PHP) you have sessions that are too short! (10-15 minutes by default).

Sessions In The Database: Most technologies provide the ability to store sessions in the database. There are several advantages. You have better control over the length of a session, as you can control when the session data is cleared out. You have better security because the data is not stored in a common area as it is in PHP by default. You also can run a server farm with several servers all retrieving session data from the same database. Neither ASP or PHP allow for a server farm in their sessions without a database.

PHP Default Session Storage (File System): In PHP, by default session data is stored in files on the server. Each file is named after a cookie that is stored on the client computer. This session cookie (PHPSESSID) presumably survives on the client side until all windows of the browser are closed. If the file on either end is deleted (server or client) the session is deemed not to be a match, and the session is invalid.

 Each session has a ‘timeout’ declared in seconds in the PHP.INI as session.gc_maxlifetime. This timeout (default of 24 minutes) is like a clock that is ‘restarted’ every time a user hits a page that uses a session (session_start()). That means a user can ‘reload’ a session-oriented page and restart the timer.

 The current value of session.gc_maxlifetime (gc stands for ‘garbage collection’) can be viewed via the phpInfo() command.

 If we have been given the permission to overwrite the PHP.INI file, we can do so, for example in our config_inc.php file:

 ini_set('session.gc_maxlifetime', '3600'); //set session duration (maxlifetime) to 1 hour - 60 x 60 x 1

 Sessions on Shared Hosts: By default, PHP stores all session files into one directory (usually /tmp on Linux). Problems can occur if our sessions are mixed with the sessions of others on a shared host. For example, the shortest duration of all hosted sessions could affect our sessions, invalidating our settings. Therefore we have a reason to store session data elsewhere. On Zephir, we moved the location where session data was stored:

 ini_set('session.save_path','/home/classes/horsey01/sessions');

 This helps in two ways. We have a more secure website as other customers whose sites were compromised are less likely to hijack our session data Links to an external site., and we now control the duration of our own sessions. When we move session data to a database table, we’ll have even greater control.

 We can also set the duration of the session cookie on the client:

 $cookie_path = "/";

$cookie_timeout = 60 * 30; // in seconds

session_set_cookie_params($cookie_timeout, $cookie_path);

 Destroying The Session: When a program elects to eliminate a session with the session_destroy() command, for example when we click logout in a PHP web application, the file is removed on the server.

 If there is no explicit session_destroy() command, the session data on the server survives until PHP elects to remove old session data via a process called ‘garbage collection’.

 Garbage Collection: On every call to session_start(), PHP performs a calculation that determines if expired session data should be eliminated. So a session file can be deleted after it’s session.gc_maxlifetime, but it may reside on the server longer, depending on the amount of sessions created. The more sessions are used on a particular server, the more frequently the possibility of garbage collection can occur. On a very quiet site, sessions could in theory last quite a long time!

 There are 3 PHP.INI settings which relate to session garbage collection:

  

PHP.INI value name

default

Changeable

session.gc_maxlifetime

1440 seconds

PHP_INI_ALL

session.gc_probability

1

PHP_INI_ALL

session.gc_divisor

100

PHP_INI_ALL

 

session.gc_probability in conjunction with session.gc_divisor determines the probability that the gc (garbage collection) routine is started. In this case the gc_probability is divided by the gc_divisor, giving a 1% chance that the gc process starts on a particular call to session_start().

 Session Issues: So we have a session cookie with that lasts until the browser is closed or the session cookie expires, but the garbage collector might delete the session file if the gc is called. This can be a problem if a user is filling out a form and walks away from the computer for a time. If it’s longer than the session file on the server is available, the session could have timed out. (For example the browser window is open longer than 24 minutes before a form is submitted).

 Taking Control Of The Session: Besides the default method of using collective file storage for session data, presumably either server memory or a database table could also be used for server side session storage. The method used is configured by the session.save_handler parameter in PHP.INI file.

 When the PHP session.save_handler parameter is set to user, PHP expects the developer to create functions for each of the following session related tasks: (description of tasks adapted from PHP Session Management by Brainbell.com Links to an external site.)

 open(string save_path, string session_name) returns boolean

Called by PHP when session_start() is called to access the session store. PHP passes the php.ini parameters session.save_path and session.name as arguments to this function, and these arguments are used to locate the session store. By default, session.save_path is set to /tmp to indicate the directory for the files storage method, and session.name is set to PHPSESSID as the name of the session ID cookie. These parameters select the database and table used to store session variables.

 close( ) returns boolean

Called by PHP at the end of a script when a session is closed. The function should return false if an error occurs during the close operation and true on success.

 read(string session_id) returns mixed (session array)

Called by PHP to read the variables for the session identified by session_id when a session is initialized. The function returns a string that contains the serialized session variables. The PHP engine converts the string to the individual session variables and sets up the $_SESSION array. If no session is found, the function should return a blank string. The function should return false if an error occurs during the read operation and true on success.

 write(string session_id, string values) returns boolean

This function is called by PHP when session variables are updated and when a session is initialized. This function is passed the ID of the session, and the session variables serialized into a single string by PHP. The implementation of write( ) must store the serialized string associated with the session, and record the time the session was last accessed. The serialized string stored for the session is returned by the read( ) handler. PHP uses this function not only to update session variables but to record the last access time when a session is initialized. The function should return false if an error occurs during the write operation and true on success.

 destroy(string session_id) returns boolean

Called by PHP when the session identified by session_id is destroyed. Removes storage dedicated to the identified session. The function should return false if an error occurs during the destroy operation and true on success.

 gc(int max_lifetime) returns boolean

Called by PHP with a probability set by session.gc_probability when a session is initialized. Removes the data and variables stored by dormant sessions. The value of session.gc_maxlifetime is passed to this function and is used to determine which are idle sessions. If the garbage collection handler is executed without error, it should return true.

 While the return types and the parameters passed to the functions must conform to the prototypes listed here, the actual function names can be different. These functions need to be registered with PHP using session_set_save_handler():

 session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)

Registers a set of PHP function names as the callback functions for user-defined session management. The arguments to this function are the names of the functions. The six parameters passed to session_set_save_handler() are interpreted as the names of the open, close, read, write, destroy, and gc functions. The location of the functions as parameters identified in session_set_save_handler() determine which function will perform which task. We’ll give similar names to our functions so we can keep the functions straight.

 Overriding Default Session Methods: When we decide to write our own session handling methods (as described above) we’ll need to provide our own function for each of the above. Here are the functions we’ll use to replace the default session functions:

 

Default Session Function

Our Function

Purpose

open()

session_open()

Initiates the session – We’ll use this to connect to our database

close()

session_close()

Ends a session script. (End of a PHP page) We’ll use this to close the db connection.

read()

session_read()

Retrieves session data – Will be read from the database

write()

session_write()

Saves/overwrites session data – Will write session data to the DB

destroy()

session_eliminate()

Deletes session data, end the session – deletes session data in the DB

gc()

session_clean()

Cleans up old session data – deletes old session data from DB

 

Once we write the code to handle all of these functions, we’ll override and assign them inside our config_inc.php file:

 session_set_save_handler('session_open', 'session_close', 'session_read', 'session_write', 'session_eliminate', 'session_clean');

 Database Sessions: We can setup our application using the technique above to allows sessions to be stored in the database.  Please view the contents of the following zip file for details: Database Sessions Zip File Links to an external site.