Login

Session Handler with the Registry Design Pattern

In this second part of a series, I demonstrate how easy it is to define a session-based registry class based on the abstract parent created in the first tutorial. The straightforward creation process means you shouldn’t have major problems building your own registry classes or even improving the ones that you’ve learned so far in this series.

Even now, many PHP developers are reluctant to implement the registry design pattern. Using the pattern seems similar to using the "evil" and deprecated global variables. But the truth is that, when used in a conscientious and responsible manner, the pattern can be really helpful. Its functionality allows you to retrieve and save resources (usually objects, although other data types are valid as well) throughout different points of an application using a predefined storage mechanism.

What’s more, implementing the pattern in PHP is such an approachable process that it’s possible to create all sorts of registries even if you have only an average background in classes and objects. It’s that simple, really.

This doesn’t mean, however, that registries should be considered outdated structures that must be deprecated in favor of more effective solutions. In fact, some well-established, enterprise-level frameworks, including one of the most well-known contenders in the field, namely the Zend Framework (http://framework.zend.com), implements a static registry via its Zend_Registry component. This can be manipulated at will by means of a neat variety of options.

Of course, you don’t need to build an entire framework from scratch to understand the logic that stands behind the registry pattern. To prove that point, in the preceding part of this article series I went thought the development of a simple hierarchy composed of two basic classes. The first one was an abstract Singleton that defined the structure of generic registries, and the second one was a refined implementation of the abstract parent, tasked with saving and fetching resources by using a private array.

While this sample hierarchy of classes does a decent job of illustrating how functional registries can be when implemented with some constraints, it’d be useful to create yet another registry class that uses a mechanism different from plain arrays to fetch and store resources across several points of an application. With that idea in mind, in this second chapter of the series I’m going to demonstrate how to build an additional registry, which will behave like a simple session handler.

Now, let’s start building the session-based registry.

{mospagebreak title=Review: building an array-based registry}

As usual, before I begin explaining how to create the session-based registry class mentioned in the introduction, first I’d like to spend a few moments reintroducing the source code of the classes defined in the previous part of the series. It used the "get_called_class()" function available from PHP 5.3 to build a hierarchy of Singleton registries. Here’s how the classes in question were initially created, starting with the corresponding abstract parent:

(AbstractRegistry.php)

<?php

abstract class AbstractRegistry

{

protected static $_instances = array();

// get Singleton instance of the registry (uses the ‘get_called_class()’ function available in PHP 5.3)

public static function getInstance()

{

// resolves the called class at run time

$class = get_called_class();

if (!isset(self::$_instances[$class]))

{

self::$_instances[$class] = new $class;

}

return self::$_instances[$class];

}

// overridden by some subclasses

protected function __construct(){}

// prevent cloning instance of the registry

protected function __clone(){}

// implemented by subclasses

abstract public function set($key, $value);

// implemented by subclasses

abstract public function get($key);

// implemented by subclasses

abstract public function clear();

}

As you can see above, understanding the driving logic of the previous abstract registry is a straightforward process. All that this class does is implement its Singleton "getInstance()" method and declare the remaining ones abstract (with the exception of the pertinent constructor, naturally).

With this abstract parent already up and running, creating a concrete registry that saves and fetches resources from an internal array is as simple as creating the following subclass. Take a look at it, please:

(ArrayRegistry.php)

<?php

class ArrayRegistry extends AbstractRegistry

{

private $_data = array();

// save new data to the array registry

public function set($key, $value)

{

$this->_data[$key] = $value;

}

// get data from the array registry

public function get($key)

{

return isset($this->_data[$key]) ? $this->_data[$key] : NULL;

}

// clear the state of the array registry

public function clear()

{

$this->_data = array();

}

}

There you have it. While the new "ArrayRegistry" class only implements three basic and easy-to-follow methods, it encapsulates the functionality required for handling resources (be it strings, numbers or objects) throughout different stages of an application via a single private array. That’s not rocket science, is it?

If you’re interested in seeing how to put this class to work, take a look at the following example. It shows how to use the class to store the full name of an old, famous writer to the class’s $_data array, and how to retrieve it at a later time. Here’s how the example in question looks:

// include source classes

require_once ‘AbstractRegistry.php’;

require_once ‘ArrayRegistry.php’;

// get Singleton instance of the ArrayRegistry class

$arrayRegistry = ArrayRegistry::getInstance();

// save some data to the array registry at one point of the application

$arrayRegistry->set(‘user1’, ‘Robert Louis Stevenson’);

// get data from the array registry at some other point of the application

echo ‘Full name of user1 : ‘ . $arrayRegistry->get(‘user1’);

See how easy it is to use this array-based registry? I bet you do! To make the above example a little more educational and "literary," the resource being saved and fetched afterward is a string containing the author of the classic terror novel "The Strange Case of Dr. Jekyll and Mr. Hyde" (http://en.wikipedia.org/wiki/Strange_Case_of_Dr_Jekyll_and_Mr_Hyde), (which both scared and fascinated me in my childhood). It’s possible to handle other kinds of data, such as numbers, arrays and even objects.

So far, so good. Now that you’ve recalled how to work with the previous registry classes, it’s time to continue exploring the functionality offered by this pattern. Therefore, in the next section I’m going to demonstrate how to create a whole new registry class whose underlying storage mechanism will be the superglobal $_SESSION PHP array.

To learn more about how this session-based registry will be defined, click on the link that appears below and keep on reading.

{mospagebreak title=Building a session-based registry}

In reality, building a session-driven registry is very similar to creating one that handles resources via arrays, except for some tiny subtleties that are easy to guess: first, the registry must be capable of creating and destroying sessions through specific methods; and second, all of the resources must be stored on the familiar $_SESSION PHP array.

With that said, here’s the definition of this whole new registry class, which fits the aforementioned requirements in a pretty decent way:

(SessionRegistry.php)

<?php

class SessionRegistry extends AbstractRegistry

{

// protected constructor

protected function __construct()

{

session_start();

}

// serve data to the session registry

public function set($key, $value)

{

$_SESSION[$key] = $value;

}

// get session data from the session registry

public function get($key)

{

return isset($_SESSION[$key]) ? $_SESSION[$key] : NULL;

}

// clear the state of the session registry

public function clear()

{

session_start();

session_unset();

session_destroy();

}

}

As I explained a moment ago, creating a registry that saves and fetches session data is an approachable process that doesn’t bear any further discussion. In the class above, the constructor is responsible for creating/resuming a session, while the "clear()" method is charged with destroying it by using some session-related PHP functions, which you’ve surely used hundreds of times before.

Disguised under the rather obscure name of "session-based registry," the previous class is nothing but a simple (yet functional) session handling class that allows you to manipulate session data via a couple of setters and getters, and nothing else.

So, do you understand how this registry does its thing? Great. Now, it’s time to leap forward and give it a try, so you can see for yourself if it works as expected. This testing process will be accomplished in the following section, so go ahead and read the lines to come.

{mospagebreak title=The session-driven registry in action}

Below you’ll find an example that shows how to work with the session registry class that you saw before. Here it is:

// include source classes

require_once ‘AbstractRegistry.php’;

require_once ‘SessionRegistry.php’;

// get Singleton instance of the SessionRegistry class

$sessionRegistry = SessionRegistry::getInstance();

// save some data to the session registry

$sessionRegistry->set(‘user2’, ‘Susan Norton’);

// get data from the session registry

echo ‘Full name of user2 : ‘ . $sessionRegistry->get(‘user2’);

Mission accomplished. As you can see, storing and retrieving resources by using the Singleton instance of the previous "SessionRegistry" class is a straightforward process that can be grasped in a snap. Again, for demonstration purposes the class performs the corresponding saving and retrieval tasks on a sample string, but a registry (be it static or functional at instance-level) will most likely be utilized with objects. In either case, the code fragments included in this tutorial should provide you with the right pointers to grasp the underlying logic of building several registries in PHP.

Lastly, if you feel adventurous and want to expand your current programming skills, I suggest you use Composition instead of Inheritance and create registries that utilize different storage mechanisms, which can be injected into a class that consumes a common interface. In doing so, you’ll be taking advantage of the benefits offered by Polymorphism. What are you waiting for? Go ahead and start coding!

Final thoughts

Over the course of this second part of the series, I demonstrated how easy it is to define a session-based registry class based on the abstract parent created in the first tutorial. This creation process was extremely straightforward, so in theory you shouldn’t have major problems building your own registry classes or even improving the ones that you learned so far in this series.

In the last article, I’m going to set up a final example that will put all of these sample registry classes to work together. Now that you know what to expect from that final installment, you don’t have any excuses to miss it!