Creating the Singleton design pattern in PHP5 Creating the Singleton design pattern in PHP5 php php

Creating the Singleton design pattern in PHP5


/** * Singleton class * */final class UserFactory{    /**     * Call this method to get singleton     *     * @return UserFactory     */    public static function Instance()    {        static $inst = null;        if ($inst === null) {            $inst = new UserFactory();        }        return $inst;    }    /**     * Private ctor so nobody else can instantiate it     *     */    private function __construct()    {    }}

To use:

$fact = UserFactory::Instance();$fact2 = UserFactory::Instance();

$fact == $fact2;

But:

$fact = new UserFactory()

Throws an error.

See http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static to understand static variable scopes and why setting static $inst = null; works.


Unfortunately Inwdr's answer breaks when there are multiple subclasses.

Here is a correct inheritable Singleton base class.

class Singleton{    private static $instances = array();    protected function __construct() {}    protected function __clone() {}    public function __wakeup()    {        throw new Exception("Cannot unserialize singleton");    }    public static function getInstance()    {        $cls = get_called_class(); // late-static-bound class name        if (!isset(self::$instances[$cls])) {            self::$instances[$cls] = new static;        }        return self::$instances[$cls];    }}

Test code:

class Foo extends Singleton {}class Bar extends Singleton {}echo get_class(Foo::getInstance()) . "\n";echo get_class(Bar::getInstance()) . "\n";


PHP 5.3 allows the creation of an inheritable Singleton class via late static binding:

class Singleton{    protected static $instance = null;    protected function __construct()    {        //Thou shalt not construct that which is unconstructable!    }    protected function __clone()    {        //Me not like clones! Me smash clones!    }    public static function getInstance()    {        if (!isset(static::$instance)) {            static::$instance = new static;        }        return static::$instance;    }}

This solves the problem, that prior to PHP 5.3 any class that extended a Singleton would produce an instance of its parent class instead of its own.

Now you can do:

class Foobar extends Singleton {};$foo = Foobar::getInstance();

And $foo will be an instance of Foobar instead of an instance of Singleton.