PHP Database Based Session Handling


Due to a move to a multi-server environment at work to cope with peak time performance I was asked to implement a replacement to PHP’s standard session handling so that sessions would work in this new environment.

In PHP 5.4 it is possible to use a simple function for setting a replacement session handler if it implements the SessionHandlerInterface however for compatibility I settled for the older format. Which in the case of my class resulted in:

From the above sample it should be clear to see that we require a database connection (injected into the class to reduce coupling) as well as defined methods for CRUD (create, read, update, delete), a method to handle garbage collection as well as open / close methods for storage setup and of course a construct for taking the database object at time of instantiation.

Let’s go through these methods in turn.

__construct

Simple taking and storing of a PDO object, the type hint will ensure that only a valid database connection will be accepted. Note that PHP type hints will only work with PHP 5.3+, this could be replaced with a simple is_a check.

open

This is where we need to ensure that our data storage is ready. In our case this is of course a database table so we need to ensure it exists, and create it if it does not. The parameters passed to the method are not actually used in this instance but must still be included in the method definition.

close

This is the counter method to __construct / open, here we can simply null the database connection object.

read

The R in CRUD, this function takes a sessionId and returns the session data, which leads to a simple SELECT query method.

The only point of note here really is the commented out section. I had added this for some extra error checking however the behaviour of PHP’s session storage caused this to break the whole thing. This seemed to be due to PHP doing a read before a write for a given session, I am assuming this is a mechanism for avoiding collisions.

write

This method forms both the C and U in CRUD, being responsible for both creation and updating of session data by id, this naturally leads to use of the REPLACE SQL statement which will update a record with a matching primary key and insert otherwise.

destroy

The delete method, nice and simple.

gc

Garbage collection is the process of removing out of date data which is no longer required, in this case we are referring to session data for users who have signed out / timed out. This is simply a case of removing any sessions beyond the max lifetime (set using session.gc_maxlifetime) or with NULL values.

During testing I found it necessary to force garbage collection to ensure that I could see it in action, garbage collection is run on a probability basis (so there is a chance of it being run when a script executes), by default this is 1 in 1000 but this can be altered by changing the session.gc_divisor and session.gc_probability, setting these so that they match will result in garbage collection always being run however remember to change these settings back for production environments as there will otherwise be a hit on performance.

Summary

I have put up my complete class as a gist. It should be clear that other mechanisms such as file storage could just as easily be used to replace standard storage be implementing the same methods as above. Replacing your session storage can be a requirement for an application depending on your environment, however it has other desirable aspects not the least of which being the ability to separate out session storage for different systems under a single domain.

About Ingmar Boddington

Codemonkey, Sheffield, UK
This entry was posted in PHP and tagged Databases, PHP, Sessions. Bookmark the permalink.