#native_company# #native_desc#
#native_cta#

Clustering in PHP: Session Management

By John Barlow
on November 26, 2013

In the first two parts of this series (Introduction to Clustering in PHP and Clustered File Systems and PHP), we explored using the file system in various configurations to help cluster PHP. This final installation will explore another method that doesn’t utilize PHP’s session management in any way.

Sessions Without Sessions?

When you first read that, it seems almost to be blasphemy. How can you have a session, without having a session? It isn’t as difficult as it sounds when you break down what makes up a session. Typically, a user’s session consists of an identifier on the client side (in a cookie) that is a pointer to information on the server side. When a new request comes in with that identifier, the system understands that you are, well, you and loads any previous data that was associated with you from your last page load. Most programming languages implement session management to make things convenient, but you don’t have to use them if you carry this concept forward.

Custom Sessions, the Basics

To create our custom session, we need a few things:

  • * Cookie to store the session ID
  • * Data store for the session information
  • * A bit of code to glue it all together

Cookies are probably the easiest part of this new scheme. For a refresher, to set up a custom PHP cookie:

setcookie("MYCOOKIE", <value>); 

When the request comes in, instead of starting the PHP session, you just need to read the cookie value:

$_COOKIE["MYCOOKIE"]; 

The Almighty Data Store

Now that we have the cookie creation/retrieval working, the next step is to set up a place for the session information to reside. If we were using the standard PHP sessions, this would be the hard disk (needing the methods we previously discussed for clustering). In this case, I want to use the database to persist the information. The reasons are as follows:

  • * Databases are designed to be data stores
  • * Most databases have built-in mechanisms for clustering/redundancy
  • * Using a database makes your code portable and not tied to a specific infrastructure
  • * Databases are designed for concurrent requests

A very simple (albeit insecure) way of tying this all together is to store a database ID as the data of your session cookie. Ultimately, you would want to wrap this in some kind of hash/salt combo, but for demonstration purposes we will keep this simple.

The Flow

When the request comes in, your custom session code needs to check $_COOKIE["MYSESSION"] to see if a previous session exists. If it does exist, use the value of the cookie to look up and load your session from the database. If it doesn’t exist, generate an id and create a row in the database. Alternatively, you could just write a blank row and use the auto-increment id from the table.

After we have a row and id, we can store things to our session. I would suggest setting up a session utility class with methods for reading and writing values that abstract the saving and loading from the database. Instead of using the $_SESSIONscope directly, you would use your class.

$mySession = new MySession();
$mySession->storeValue("key", "value");
$mySession->getValue("key"); 

Every time storeValue is called, it serializes “value” to the “key” in your session, and saves it to the database. Likewise, getValue() runs a query to load your session from the DB and pull out the key. If you wanted to get fancy, you could even implement caching so that getValue()was smart enough to only load the database information once and pull data from memory.

So… About That Clustering…

Now that you have your custom Session object reading and writing to a database, all we have left to do is get this cluster started. Fortunately, most modern databases have this built-in, and there are a ton of resources out there to help you get it set up. I’ve looked into MySQL, and it really is stupidly easy to set up a cluster. So, the answer to this is dependent on the database back end you decide to use. However, getting your session object is the hard part – let the database do the rest of the heavy lifting for you.