在PHP5中创建Singleton设计模式

如何创建一个使用PHP5类的Singleton类?


/**
 * 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()
    {

    }
}

使用:

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

$fact == $fact2;

但:

$fact = new UserFactory()

抛出一个错误。

请参阅http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static以了解静态变量作用域以及为什么设置static $inst = null; 作品。


PHP 5.3允许通过后期静态绑定来创建一个可继承的Singleton类:

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;
    }
}

这解决了这个问题,即在PHP 5.3之前,任何扩展单例的类都将生成其父类的实例,而不是它自己的实例。

现在你可以这样做:

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

而$ foo将成为Foobar的一个实例,而不是Singleton的一个实例。


不幸的是,当有多个子类时,Inwdr的答案就会中断。

这是一个正确的可继承Singleton基类。

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];
    }
}

测试代码:

class Foo extends Singleton {}
class Bar extends Singleton {}

echo get_class(Foo::getInstance()) . "n";
echo get_class(Bar::getInstance()) . "n";
链接地址: http://www.djcxy.com/p/82175.html

上一篇: Creating the Singleton design pattern in PHP5

下一篇: What is so bad about singletons?