Zend Framework: MongoDB session saveHandler

31 05 2011

In this third part about the Zend Framework i am diving into the world of Zends implementation for sessions. Sessions are used to provide a way to save data between different page requests.

The Zend Framework has an easy way of managing sessions by creating a new instance of the Zend_Session_Namespace class. This class provides an easy to use API on the Zend_Session managed superglobal $_SESSION. By default the session data is saved to the filesystem which works perfect for simple applications using a single webserver but will be more problematic when multiple webservers are used all with their own filesystem.

A solution for this problem is saving the session data to a central database which is available to all webservers. The Zend Framework provides a class which can be used for this: Zend_Session_SaveHandler_DbTable which can be configured completely as a resource within the application.ini file.

Using the database as a central source for session data gives some other worries though:

  • You have to make sure the database will be available at all time
  • Clustering databases for high availability is something not all persons have knowledge on
  • Managing the session tables within these databases poses some headaches when changes to the existing table are needed.

Another approach is using a memory based store like memcache, but in this post i would like to use the “new” kid in town called MongoDB, a scalable, high-performance, open source, document-oriented database. For this we are going to write a new session save handler for Zend Framework called GcLib_Zend_Session_SaveHandler_MongoDb. The source of this class can be downloaded here.

We start by creating the class GcLib_Zend_Session_SaveHandler_MongoDb implementing the interface Zend_Session_SaveHandler_Interface. This interface contains six methods we need to implement:

  1. open($save_path, $session_name): This method should open a connection to MongDB and return a boolean indicating its success. In our case we do not really need the parameters for save path and session so we ignore the values passed into the method.
  2. close(): This method should normally close the connection you opened in the open() method, but for convenience we just return true.
  3. read($id): This method has a parameter containing the session id. With this id we will find the session data in MongoDB. Beware, this function should alway return a literal, so never return NULL or false when no session data is returned from the database!
  4. write($id, $data): This method actually stores the session data in MongoDB. The id parameter contains the session id (which is the same as the value kept in the session cookie). The data parameter contains the serialized session data. These values are both stored in a MongoDB document together with a lifetime property containing the acces time. The method returns a boolean indicating its success.
  5. destroy($id): This method removes the session data and returns also a boolean indicating its success.
  6. gc($maxlifetime): This methods behaves as the garbage collector and removes sessions which are stale.
Last method i will discuss is the constructor for the save handler class. The constructor has one parameter which expects a Zend_Config instance or an array containing the options for connecting to MongoDB. One of the options is “servers”, which holds the MongoDB server(s) to connect to. The other options provided by the parameter will be used as optional connect options which are more explained here.
Note: For now the database and collection are hardcoded: db=”php”, collection=”sessions”

Zend configuration of the MongoDB save handler

To use the MongoDB save handler we add the following line to the application.ini file:

resources.session.saveHandler.class = "GcLib_Zend_Session_SaveHandler_MongoDb"

With this single resource line Zend_Session will now use our save handler class. Add the following resource line to connect to a single MongoDB instance:

resources.session.saveHandler.options.servers = "localhost:27017"

The “servers” resource  option will hold the MongoDB connect string, which is localhost using the default port 27017. It is possible to connect to multiple servers by adding more host:port entries separated by commas. When the MongoDB is started as a standalone server it is advisable to add the “persist” option line like below to use a persistent connection (using the name “x”):

resources.session.saveHandler.options.persist = "x"

It is also possible to connect to a set of MongoDB servers started in a replication set. Read the MongoDB documentation for a tutorial on howto setup this configuration. For connecting to the primary, remove the persist option and add the following option line to application.ini:

resources.session.saveHandler.options.replicaSet = "true"

Just play around by creating a new php session and terminating one of the servers within the replicated set: failover at your fingertips.



One response

7 06 2013

Great tutorial
Any ideas how to unserialize the data in your sessions collection

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: