Cloud Zone is brought to you in partnership with:

After teaching math (and a little computer science) for 14 years, Brian changed careers in 2006 with the idea that getting out of his comfort zone would be good. So now he works as a writer and programmer at Microsoft who specializes in PHP and Windows Azure. Brian is a DZone MVB and is not an employee of DZone and has posted 82 posts at DZone. You can read more from them at their website. View Full User Profile

Handling PHP Sessions in Windows Azure

10.19.2011
| 3586 views |
  • submit to reddit

One of the challenges in building a distributed web application is in handling sessions. When you have multiple instances of an application running and session data is written to local files (as is the default behavior for the session handling functions in PHP) a user session can be lost when a session is started on one instance but subsequent requests are directed (via a load balancer) to other instances. To successfully manage sessions across multiple instances, you need a common data store. In this post I’ll show you how the Windows Azure SDK for PHP makes this easy by storing session data in Windows Azure Table storage.

In the 4.0 release of the Windows Azure SDK for PHP, session handling via Windows Azure Table and Blob storage was included in the newly added SessionHandler class.

Note: The SessionHandler class supports storing session data in Table storage or Blob storage. I will focus on using Table storage in this post largely because I haven’t been able to come up with a scenario in which using Blob storage would be better (or even necessary). If you have ideas about how/why Blob storage would be better, I’d love to hear them.

The SessionHandler class makes it possible to write code for handling sessions in the same way you always have, but the session data is stored on a Windows Azure Table instead of local files. To accomplish this, precede your usual session handling code with these lines:

    require_once 'Microsoft/WindowsAzure/Storage/Table.php';
    require_once 'Microsoft/WindowsAzure/SessionHandler.php';
    $storageClient = new Microsoft_WindowsAzure_Storage_Table('table.core.windows.net', 
                                                              'your storage account name', 
                                                              'your storage account key');
    $sessionHandler = new Microsoft_WindowsAzure_SessionHandler($storageClient , 'sessionstable');
    $sessionHandler->register();

Now you can call session_start() and other session functions as you normally would. Nicely, it just works.

Really, that’s all there is to using the SessionHandler, but I found it interesting to take a look at how it works. The first interesting thing to note is that the register method is simply calling the session_set_save_handler function to essentially map the session handling functionality to custom functions. Here’s what the method looks like from the source code:

    public function register()
    {
        return session_set_save_handler(array($this, 'open'),
                                        array($this, 'close'),
                                        array($this, 'read'),
                                        array($this, 'write'),
                                        array($this, 'destroy'),
                                        array($this, 'gc')
        );
    }

The reading, writing, and deleting of session data is only slightly more complicated. When writing session data, the key-value pairs that make up the data are first serialized and then base64 encoded. The serialization of the data allows for lots of flexibility in the data you want to store (i.e. you don’t have to worry about matching some schema in the data store). When storing data in a table, each entry must have a partition key and row key that uniquely identify it. The partition key is a string (“sessions” by default, but this is changeable in the class constructor) and the the row key is the session ID. (For more information about the structure of Tables, see this post.) Finally, the data is either updated (it it already exists in the Table) or a new entry is inserted. Here’s a portion of the write function:

$serializedData = base64_encode(serialize($serializedData));
 
$sessionRecord = new Microsoft_WindowsAzure_Storage_DynamicTableEntity($this->_sessionContainerPartition, $id);
$sessionRecord->sessionExpires = time();
$sessionRecord->serializedData = $serializedData;
 
try
{
    $this->_storage->updateEntity($this->_sessionContainer, $sessionRecord);
}
catch (Microsoft_WindowsAzure_Exception $unknownRecord)
{
    $this->_storage->insertEntity($this->_sessionContainer, $sessionRecord);
}

Not surprisingly, when session data is read from the table, it is retrieved by session ID, base64 decoded, and unserialized. Again, here’s a snippet that show’s what is happening:

    $sessionRecord = $this->_storage->retrieveEntityById(
        $this->_sessionContainer,
        $this->_sessionContainerPartition,
        $id
    );
    return unserialize(base64_decode($sessionRecord->serializedData));

As you can see, the SessionHandler class makes good use of the storage APIs in the SDK. To learn more about the SessionHandler class (and the storage APIs), check out the documentation on Codeplex. You can, of course, get the complete source code here: http://phpazure.codeplex.com/SourceControl/list/changesets.

As I investigated the session handling in the Windows Azure SDK for PHP, I noticed that the absence of support for SQL Azure as a session store was conspicuous. I’m curious about how many people would prefer to use SQL Azure over Azure Tables as a session store. If you have an opinion on this, please let me know in the comments.

References
Published at DZone with permission of Brian Swan, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Rehman Khan replied on Sat, 2012/02/25 - 4:47am

I had the experince that the table storage session handler slows down my application about more than 300ms. Have you noticed the same issue? On the other hand I was trying to use SQL Azure as session storage but the symfony plugin I found does not really work with MSSQL/SQL Azure :(

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.