Late Static Bindings in PHP 5.3 with the Abstract Factory Pattern

In this fourth part of the series, I demonstrate how Late Static Bindings can be useful for implementing the abstract factory design pattern. The feature will be used at the instance level within the constructor of an abstract factory class, where at least one of its concrete implementations is tasked with factoring a couple of block-level (X)HTML objects, such as divs and paragraphs.

Among the new features that have been packaged with PHP 5.3, there’s one that turns out to be remarkably useful during the development of object-oriented applications. It allows programmers to efficiently solve common issues that occur when it’s necessary to deal with hierarchies of classes in a static context.

Yes, as you may already have guessed, in this case I’m talking about Late Static Bindings (LSB), which can be used for determining at runtime from which class a static method has been called. It’s possible, however, that you’re wondering what the big deal is, right?

Well, I’m glad you asked! While at first glance this ability seems to have little or no importance, especially when compared to other widely-marketed improvements added to the language (such as native namespaces and anonymous functions), LSB are actually a handy enhancement that makes it considerably easier to create flexible hierarchies of classes. 

To illustrate how helpful LSB can actually be in a concrete use case, in previous parts of this series I showed how to use them to build a couple of basic, yet functional, registry classes. The first of these classes was an abstract one that implemented a static Singleton method called “getInstance(),” while the second class was a simple array-based registry derived from the corresponding abstract parent. This hierarchy normally wouldn’t be especially interesting, but thanks to the functionality of LSB, the above-mentioned method returned to client code (when possible) an instance of the class from which it was invoked. Not too bad, huh?

In addition, I showed how to replicate the previous hierarchy by using the “get_called_class()” function, available since PHP 5.3.0, thus simplifying the  definitions of the classes involved. Nonetheless, it’s fair to stress that the use of LSB isn’t limited to facilitating the implementation of the registry pattern in static environments. They can be utilized at the instance level as well. Therefore, in this fourth installment of the series I’m going to demonstrate how to take advantage of this capability by constructing an abstract factory class whose concrete implementations will be responsible for creating a few HTML widgets.

Are you feeling eager to see how this will be done? Then don’t hesitate; start reading!   

{mospagebreak title=Review: using Late Static Bindings to build registry classes}

As I mentioned in the introduction, PHP 5.3 includes the “get_called_class()” function, which allows you to replicate most of the functionality of Late Static Bindings without having to explicitly use the keyword “static.” Simply put, the function permits you to determine at runtime which class was called from a given static method. In case you haven’t read the previous article of the series, where I discussed how to use this function in the construction of a flexible hierarchy of Singleton registry classes, below I listed the definitions of these registries, starting with the abstract parent. Here it is:   

(RegistryAbstract.php)

 

 

abstract class RegistryAbstract

{

    protected static $_instances = array();

   

    // get Singleton instance of the registry

    public static function getInstance()

    {

        $class = get_called_class();

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

        {

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

        }

        return self::$_instances[$class];

    }

       

    // implemented by registry subclasses

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

   

    // implemented by registry subclasses

    abstract public function get($key);

   

    // implemented by registry subclasses

    abstract public function clear();         

}

As its name suggests, the above “RegistryAbstract” class defines the structure and partial functionality of generic registries, a process that’s very easy to follow. Prior to PHP 5.3, its “getInstance()” Singleton method would always attempt to return an instance of this abstract class, therefore raising a fatal error. However, with the introduction of the “get_called_class()” function, this issue can be solved with minor hassles.

To understand how useful this function really is, pay attention to the definition of the following class. It is a simple array-based registry derived from the previous abstract parent: 

(ArrayRegistry.php)

 

 

<?php

 

class ArrayRegistry extends RegistryAbstract

{

    private $_data = array();

   

    // save data to the registry

    public function set($key, $value)

    {

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

        return $this;

    }

   

    // get data from the registry

    public function get($key)

    {

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

    }

 

    // clear the registry

    public function clear()

    {

        $this->_data = array();

    }        

}

To be frank, the definition of this concrete registry is nothing spectacular, with the sole exception of a small subtlety: its inherited “getInstance()” method is still functional! But, to understand this more clearly, please take a look at the following script. It uses an instance of this registry class to fetch and save some fictional data to a private array:

<?php

 

// include source classes

require_once ‘RegistryAbstract.php’;

require_once ‘ArrayRegistry.php’;

 

try

{

    // grab the Singleton instance of the ArrayRegistry class

    $arrayRegistry = ArrayRegistry::getInstance();

    // save some users to the registry

    $arrayRegistry->set(‘user1’, ‘Julie Smith’)->set(‘user2’, ‘Mary Wilson’);

    // get the second user from the registry

    echo $arrayRegistry->get(‘user2’);

    /*

    displays the following

    Mary Wilson

    */

}

 

catch (Exception $e)

{

    echo $e->getMessage();

    exit();

}

There you have it. As the above script shows, grabbing the Singleton instance of the previous array registry class is a breeze due to the use of the “get_called_class()” function behind the scenes. Logically, deriving only one concrete registry from an abstract parent is a pretty pointless process that doesn’t fully exploit the benefits of Inheritance; nevertheless, you may want to use the earlier example as a starting point and create multiple registry classes. In doing so, you’ll realize how powerful the “get_called_class()” function can be when creating hierarchies of classes that share at least one static method.

All right, having recreated a situation where LSB can be applied successfully, it’s time to explore other possible uses of this feature. So far, I showed how to work LSB from inside a static method, and the definition of the previous “getInstance()” method is a good example of this. It’s possible, though, to take advantage of this feature when working in the object scope as well.

In the upcoming section I’m going to build a simple abstract factory class where the constructors of its concrete factories will employ LSB to create some predefined (X)HTML widgets.

Now, click on the link below and keep reading.

{mospagebreak title=Creating an abstract factory class}

The functionality of Late Static Bindings really shines when used in a static context. It’s feasible, however, to use them at the instance level with the same ease and get successful results as well. Logically, the best way to understand this concept is through some functional code, so let me provide you with an example where this feature will be utilized in the object scope.

Consider the following class, which is an abstract factory whose concrete subclasses will be responsible for factoring some basic (X)HTML objects:

(HtmlElementFactory.php)

 

 

<?php

 

abstract class HtmlElementFactory

{

    private $_element;

   

    // constructor (Late Static Bindings are used at instance level)

    public function __construct($element = ”, array $options = array())

    {

        if ($element !== ”)

        {

            $this->_element = static::create($element, $options);

        }

    }

   

    public function getElement()

    {

        return $this->_element;

    }

   

    // implemented by concrete factory classes  

    public static function create($element, array $options = array())

    {

        throw new HtmlElementFactoryException(‘This is an abstract factory and it does not create any concrete HTML element.’);   

    }  

}

 

 

 

( HtmlElementFactoryException.php)

 

<?php

 

class HtmlElementFactoryException extends Exception {}

That looks quite interesting, doesn’t it? As you can see, the above abstract factory class defines a static “create()” method, which should be implemented by eventual concrete factories to spawn specific (X)HTML objects. Even though this is a typical schema of the factory pattern, it has a small twist that you may already have noticed: yes, the factory’s constructor internally uses LSB to invoke the pertinent “create()” method.

Put in a simple way, this implies that all the child factories derived from the previous abstract parent will be able to factor (X)HTML elements either statically via the aforementioned “create()” method, or in the object scope via the constructor. In summary, we get the best of both worlds.

If this explanation sounds a little obscure and difficult to grasp, hopefully all of your doubts will vanish when I show you the definition of a concrete factory, which in this case will be tasked with factoring some block-level (X)HTML objects.

The definition of this brand new class will be shown in the next section. Thus, go ahead and read the following lines.

{mospagebreak title=Subclassing the previous abstract factory class}

Considering that the constructor of the earlier abstract factory class will invoke the static “create()” method at runtime due to the internal use of Late Static Bindings, building a concrete factory that returns to client code a couple of block-level (X)HTML objects is as simple as defining the following class: 

(BlockLevelElementFactory.php)

 

 

<?php

 

class BlockLevelElementFactory extends HtmlElementFactory

{

    // create a block-level HTML element

    public static function create($element, array $options = array())

    {

        if ($element === ‘Div’ or $element === ‘Paragraph’)

        {

            return new $element($options);

        }

    } 

}

Mission accomplished. At this point, I created a simple, yet functional, concrete factory class which overrides the static “create()” method defined by its abstract parent. In this case, the method is responsible for factoring (X)HTML objects of type “Div” and “Paragraph” respectively, but naturally it’s possible to extend its functionality by adding support for other block-level objects. Nonetheless, the most interesting facet of this class is its ability to factor the objects either statically or through its constructor. This shows how useful Late Static Bindings actually are, even when used in the object scope.

And with this final code sample I’m finishing this chapter of the series. As usual, feel free to tweak the source code of all the classes shown in this tutorial. Doing so will help you to better understand how to incorporate the functionality provided by LSB into your own object-oriented PHP applications.

Final thoughts

That’s it for the moment. Over this fourth part of the series, I demonstrated how Late Static Bindings can be quite useful when it comes to implementing the abstract factory design pattern. In the above code samples, this feature was used at the instance level within the constructor of an abstract factory class, where at least one of its concrete implementations was tasked with factoring a couple of block-level (X)HTML objects, such as divs and paragraphs.

Of course, the next logical step we must take is to define the classes responsible for creating the aforementioned (X)HTML objects. That’s exactly the topic that I plan to cover in the forthcoming tutorial of the series. Now that you know what to expect from the next installment, you don’t have any excuses to miss it!

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

chat sex hikayeleri Ensest hikaye