Login

Dynamic Registry in PHP

Segregated interfaces aren’t anything new in PHP. Simply put,a segregated interface is a regular interface whose contract provides implementers with the functionality to perform one or more specific tasks. In this second part of a series, we will be using them to create a registry system.

Segregating a monolithic interface in a set of more granulated contracts permits us to build classes that stick more efficiently to the “separation of concerns” paradigm, and additionally makes it easy to develop applications that can be easily extended by means of Composition, rather than with Inheritance.

To demonstrate how to utilize segregated interfaces, in the introductory installment of this series I developed a typical array collection class, which utilized three segregated interfaces (namely the native ones Countable, Iterator and ArrayAccess) in order to implement a structure capable of traversing arrays, as well as counting and manipulating their elements.

Segregated interfaces can be used in many scenarios and situations, apart from the one mentioned above. In this second tutorial of the series I’m going to show you how to utilize a pair of custom segregated interface in the construction of a flexible registry system. Thanks to the utilization of these interfaces along with the “Plug-in” pattern, the registry will have the ability to store/fetch/remove elements through plain arrays and via PHP sessions as well.

Taking the first step: creating a couple of segregated interfaces

I’m going to develop a simple –yet functional- dynamic registry, pretty similar to the one that I created here (http://www.devshed.com/c/a/PHP/Building-a-service-Locator-in-PHP/). As stated in the introduction, though, there will be a subtle difference, as client code consuming the registry will be able to swap between an array-based registry and one that uses PHP sessions.

(RegistrableInterface.php)

<?php

interface RegistrableInterface { public function set($key, $value);

public function get($key);

public function clear(); }

If I had to say something about the above “RegistrableInterface” interface, it would be that the contract that it defines is a very narrowed one. After all, it only declares three methods which, when concretely implemented, will allow us to save, retrieve and clear data in a storage/registry system. But why should it be more generous, if this is only the functionality that its implementers will need?

Now, since I want the different registry classes to dump the store data, I’m going to define a separate contract for performing this task. This contract, not surprisingly is established by another segregated interface called “DumpableInterface” (sorry for the name, seriously). Here it is:

(DumpableInterface.php)

<?php

interface DumpableInterface { public function dump(); }

Due to its simplicity, I think that this new interface doesn’t bear any further analysis. It’s worth noting, however, that at this point I managed to create a flexible API, thanks to the existence of a couple of segregated interfaces.

So, with the previous contracts properly defined, the next thing that must be done is to define the classes implementing the pertinent interfaces, which will handle data using different back-ends.

{mospagebreak title=Implementing PHP Segregated Interfaces}

Since the segregated interfaces created before establish a clearly-defined group of contracts, building a couple of implementers of them, capable of saving/fetching/dumping elements from different storage mechanisms is a simple process. Take a look at the following class, which is a basic array-based registry:

Effectively, the above “ArrayRegistry” class implements the previous segregated interfaces, something that gives it the ability for storing and retrieving data from a protected array, and even for dumping the whole registry. Leaving apart its simplicity, the beauty of this class is that its functionality has been achieved by agreeing two different, highly-granular contracts.

Having defined the first registry back-end, it’s time to show the one that uses internally PHP sessions. Here it is:

The logic implemented by the prior “SessionRegistry” class closely resembles the one of its counterpart “ArrayRegistry”, with a few subtle exceptions, of course. The former is a simple wrapper for the $_SESSION superglobal PHP array, something that lets it store, fetch and dump session data in a pretty straightforward fashion. Again, it’s worth to stress how this class implements the earlier segregated interfaces, in order to perform the aforementioned tasks.

So far, so good. With the two previous registry classes coexisting happily side-by-side, it’s easy to create an adapter capable of asking for them (or for any other registry back-end) in the constructor. The following class does exactly that:

Even when this new adapter class is a rather simple structure, it’s clearly a winner one! On one hand, its uses transparently the “Plug-in” pattern (http://www.devshed.com/c/a/PHP/The-PHP-Plugin-Pattern/), which provides it with the ability for switching different registry back-ends at construction time, while on the other one, the collaborator that it asks for in the constructor is actually a segregated interface, thus sticking to the commandment “Coding to an interface, not an implementation” that you’ve probably heard hundreds of times before.

And now that you grasped how the use of segregated interfaces can be of great help in the construction of a flexible, expandable registry system, the only thing that remains undone is to set up a couple of scripts that show how to utilize the system in a useful manner.

{mospagebreak title=Using PHP Registry Classes}

To demonstrate how to put to work in conjunction all the source classes and interfaces developed so far, I’m going to appeal to the functionality of basic autoloader. This class is very similar to others shown in previous articles published here at the Developer Shed network, so feel free to skip over its definition if you want to. For the sake of completeness, here’s how this autoloader looks:

Certainly, understanding how the above autoloader works is an easy-to-grasp process, so move on and take a peek at the following script, which demonstrates how to save and fetch some trivial data using the earlier array-based registry:

This example is indeed pretty basic; it shows how convenient it is to combine the power of dependency injection with the use of segregated interfaces. But, if the pertaining example doesn’t fulfill your expectations yet, pay attention to the following one, which performs the same saving/fetching process but this time by means of the session-based registry:

There you have it. As the earlier code fragment shows, swapping between different registry back-ends is pretty much like replacing a Lego block by another. Plus, thanks to the transparent use of the previous segregated interfaces, each back-end implements only the functionality required to perform the tasks it’s responsible for.

Finally, feel free to tweak all the code samples shown before, something that will let you acquire a better background on segregated interfaces, so you can take advantage of them during the development of your own object-oriented applications.

Final thoughts

Over this second part of the series, I went through the development of a basic registry system, whose respective back-ends used a few custom segregated interfaces to implement the functionality that they needed to perform their corresponding tasks. However simple, this example showed a pretty realistic use case, where the definition of some segregated interfaces made easy to establish the “appropriate” contracts for a set of related classes.

Needless to say that a segregated interface can be utilized in all sort of use cases, others than the one previously discussed. With that concept in mind, in the upcoming tutorial I’m going to demonstrate how to construct a flexible caching system, whose internal classes will made use, not surprisingly, of a user-defined segregated interface as well.