Registry Design Pattern: Complete Implementation

Welcome to the conclusion of a three-part article series that shows you how to implement the Registry design pattern in PHP. In this part, we’ll take all the classes that we’ve created so far and put them to work together.

So, if you’re a PHP developer who wants to expand your current programming skills by learning how to implement the Registry design pattern in a few simple steps without having to deal with obscure and hard-to-grasp concepts, then you’ve come to the right place.

And now that you know what to expect from these articles, it’s time to review the topics covered in the last one. In that article, I demonstrated how to create a basic, yet functional registry class. The class could save and retrieve resources across different points of an application by using the $_SESSION superglobal PHP array.

Hidden behind a fancy name, this sample class was nothing but a basic session handler that took advantage of the functionality offered by the registry pattern to do its business. This showed that registries can be used in distinct situations and with multiple persistent layers, but in all cases with similar purposes.

So far, I’ve illustrated how to build a few registry classes that used different storage mechanisms for storing/retrieving resources throughout several stages of a PHP program. That’s all well and good, but it’d be useful to show how to put all of these classes to work in conjunction, at least for educational reasons.

That’s exactly what I plan to do in this last chapter of the series, thus finishing this humble introduction to applying the registry pattern in PHP. So, don’t hesitate any longer; start reading right now!

{mospagebreak title=Review: building a basic session-based registry}

Before demonstrating how to use all the sample registry classes together, I’m going to reintroduce the example created in the previous tutorial. It was aimed at showing how to build a basic session-based registry by using a few straightforward methods.

In case you don’t recall it, the registry was derived from an abstract parent whose definition looked like this:

(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();

}

Considering that this abstract registry was covered in depth in earlier parts of the series, I’m not going to waste your time explaining once again how it works. Instead, I suggest you take a look at the source code of the following session handling class. It inherits the static “getInstance()” method defined by its parent and implements the remaining ones as well. Here’s the class in question:

(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 you can see, building a registry that saves and fetches resources from the $_SESSION superglobal array is an extremely simple process. Aside from implementing the “set()” and “key()” methods declared by the abstract parent, this class implements a couple of additional methods (including the constructor) for creating, restoring and destroying a session.

Of course, if you found it easy to understand the logic driving the earlier registry, then it’ll be even simpler for you to grasp how it can be used in a concrete case. Still not convinced? Look at the following script, which shows how to handle some session data using the Singleton instance of the registry:

// 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′);

There you have it. As the above code snippet depicts, the registry pattern can be used in multiple cases, including the implementation of a basic, yet functional session handler. As I stated in the introduction, though, in this last chapter of the series I’d like to demonstrate how to use all of the registries defined so far at the same time. Since I want to save myself from the hassle of manually loading those classes via PHP includes, in the following segment I’m going to create an autoloader, which as you’ll see in a moment, will be very easy to understand.

Now, click on the link that appears below and keep reading.

{mospagebreak title=Defining a basic autoloader class}

Since my plan here is to put all of the registries to work together, I’m going to define a basic autoloader class that will include all of these source classes behind the scenes, on request.

Having said that, here’s the source code corresponding to the aforementioned autoloader:

(Autoloader.php)

<?php

class Autoloader

{

private static $_instance;

// get Singleton instance of the autoloader

public static function getInstance()

{

if (!self::$_instance)

{

self::$_instance = new self;

}

return self::$_instance;

}

// private constructor

private function __construct()

{

spl_autoload_register(array(‘Autoloader’, ‘autoload’));

}

// prevent cloning instance of the autoloader

private function __clone(){}

// autoload a class on demand

public static function autoload($class)

{

$file = $class . ‘.php';

if (!file_exists($file))

{

require_once ‘ClassNotFoundException.php';

throw new ClassNotFoundException(‘The file containing the requested class was not found.’);

}

include $file;

unset($file);

if (!class_exists($class, false))

{

require_once ‘ClassNotFoundException.php';

throw new ClassNotFoundException(‘The requested class was not found.’);

}

}

}

(ClassNotFoundException.php)

<?php

class ClassNotFoundException extends Exception{}

If you’re used to taking advantage of the built-in autoloading capabilities offered by PHP, then the definition of the above class should be quite familiar to you. All it does is register its static “autoload()” method in the SPL stack, to include classes on demand. In addition, the class throws a couple of custom exceptions at the proper places, but this feature can be modified or even removed.

All right, having already defined a basic autoloader that include classes on request, the last step that must be taken is to set up a script that puts all the registries to work together. This will be done in the final section of this tutorial, so click on the link below and keep reading.

{mospagebreak title=Using the registry classes in a single script}

As I said in the segment that you just read, the only thing that remains undone is creating a script that uses all of the registry classes defined so far at the same time. This is exactly what the code fragment below does, so pay attention to it, please: 

<?php

try

{

// include autoloader

require_once ‘Autoloader.php';

// get instance of the autoloader

Autoloader::getInstance();

// get Singleton instance of the ArrayRegistry class

$arrayRegistry = ArrayRegistry::getInstance();

// save some data to the array registry

$arrayRegistry->set(‘user1′, ‘Linda Smith’);

// get data from the array registry

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

// 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′);

}

// catch exceptions

catch (Exception $e)

{

echo $e->getMessage();

exit();

}

Undeniably, the above script is very easy to understand. It first grabs the instance of the autoloader, and then uses each registry to save and retrieve the full names of a couple of fictional users. Even though all the registry classes shown in this example are Singletons, it doesn’t mean that all of the registries have to be created that way all the time. Keep this concept in mind, especially if you’re planning to build your own registries.

Finally, feel free to tweak all of the code samples developed in this series. This process will surely provide you with a more intimate background in implementing the registry design pattern in PHP.

Final thoughts

Sad but true, we’ve come to the end of this series. As you saw, the implementation of registry classes in PHP is actually a straightforward process that can be mastered with minor effort, even if you’re just taking your first steps in the field of object-oriented programming.

By far, the most controversial facet of the pattern is that it provides global access to resources within an application, which is not a desirable feature in all cases. So let me make a simple and pragmatic suggestion: use the pattern with due caution and responsibility.

See you in the next PHP development tutorial!

[gp-comments width="770" linklove="off" ]

chat