问题描述
如何使用PHP5类创建单身类?
推荐答案
/** * Singleton class * */ final class UserFactory { private static $inst = null; // Prevent cloning and de-serializing private function __clone(){} private function __wakeup(){} /** * Call this method to get singleton * * @return UserFactory */ public static function Instance() { 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.scope.static 了解静态变量示波器以及为什么设置static $inst = null;可以使用.
其他推荐答案
不幸的是当有多个子类时.
这是一个正确的继承的单例基类.
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";
其他推荐答案
PHP 5.3允许通过晚期静态绑定创建可遗传的单例类:
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的实例.
问题描述
How would one create a Singleton class using PHP5 classes?
推荐答案
/** * Singleton class * */ final class UserFactory { private static $inst = null; // Prevent cloning and de-serializing private function __clone(){} private function __wakeup(){} /** * Call this method to get singleton * * @return UserFactory */ public static function Instance() { 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.