Multiple inheritance in PHP with the decorator pattern

The concept of multiple inheritance in commonly known from C++. It can be a useful feature as well as a path to really messy code that is prone to unexpected behavior if one uses it without caution. See the Diamond Problem for a common example.

As you probably know, PHP does not support real multiple inheritance and if you ask me, that’s a good thing. But there are times when you may want a class to inherit features from more than one other class.

Object oriented design patterns have brought us the concept of Decorators. This pattern allows us to add behavior to classes dynamically without using the default inheritance mechanism.

To implement the Decorator design pattern, you need to build a way to tell your class when to use behavior of another one. Let’s get right to that and start by making a simple class that will use a decorator later. It will be a class that holds a simple piece of text for later display and that will use several text filters to change the contained text.

class Text
{
    private $text = null;
    
    public function __construct($text)
    {
        $this->text = $text;
    }
    
    public function __toString()
    {
        return $this->text;
    }
}

So far this thing does pretty much nothing but this about to change.

First we need to specify how our filters will be recognized. An interface will to the job:

interface TextFilter
{
    public function filter( $text );
}

All filter classes will need to implement this interface to be compatible with the class Text later. Now we can add methods for accepting filters to the Text class:

class Text
{
    private $text = null;
    private $filteredText = null;
    
    private $filters = array();
    
    public function __construct($text)
    {
        $this->text = $text;
    }
    
    public function __toString()
    {
        $this->filter();
        return $this->filteredText;
    }
    
    public function registerFilter( TextFilter $filter )
    {
        $this->filters[] = $filter;
    }
    
    private function filter()
    {
        $this->filteredText = $this->text;
        foreach ( $this->filters as &$filter ) {
            $this->filteredText = $filter->filter( $this->filteredText );
        }
    }
    
}

The Text class is now able to receive filters that implement the TextFilter interface. Before returning its contained text, it will iterate over all registered Filters and let them process the text by calling their filter() methods.

Now we need an example filter. For the sake of simplicity I will use one that just lowercases the text:

class TextFilter_LowerCase implements TextFilter
{
    public function filter($text)
    {
        return strtolower($text);
    }
}

Now we can instantiate a Text object and register the filter to it. When casting the Text object to a string by passing it to echo, the filter will process the contained text and the output will be lowercased.

$text = new Text('Some stRIng wIth a fEW UppercAse LeTTerS');
$text->registerFilter( new TextFilter_LowerCase );
echo $text;

You can register as many filters to this class as you wish and they will be processed in the order in which they where registered. This way you can implement some kind of multiple inheritance without running into the usual pitfalls of the C++ like way.

One popular example where something like this is done is the Zend Frameworks system for controller plugins. Those Plugins even utilize multiple hooks like our filter() method here.

You can add any behavior you want to a class that allows the registration of compatible decorators. Of course this example is very simple but you can easily extend it to be more comfortable to use or add some more sophisticated decorator management.