Singletons in PHP 5.3

Marc präsentiert in seiner Reihe “Ein Herz für Entwurfsmuster” das Singleton als PHP-Implementierung.

Seinen beiden Beispielen, dem klassischen und dem generischen Singleton füge ich hier eine Implementierung hinzu, die auch mit Vererbung zurechtkommt, dafür aber PHP 5.3 voraussetzt.

class MySingleton
{
    protected static $instances = array();
    
    protected function __construct() { }

    final private function __clone() { }
    
    final public static function getInstance()
    {
        $calledClassName = get_called_class();
        if (!isset(self::$instances[$calledClassName])) {
            self::$instances[$calledClassName] = new $calledClassName();
        }
        return self::$instances[$calledClassName];
    }

    // ...
}

Von dieser Klasse können nun weitere Singletons abgeleitet werden, deren getInstance-Aufruf erwartungsgemäß funktioniert (und nicht die Basisklasse zurückliefert):

class Foo extends MySingleton { }

class Bar extends MySingleton { }

$foo = Foo::getInstance();  // get_class($foo) == 'Foo'
$bar = Bar::getInstance();  // get_class($bar) == 'Bar'

Der Trick liegt hier in der Verwendung vom in PHP 5.3 eingeführten ”Late static binding” und get_called_class.