我的单例类有最终的静态方法“getInstance()”:
<?php
abstract class Singleton
{
protected static $instances;
final public static function getInstance()
{
$class = get_called_class();
if(!isset(static::$instances[$class]))
static::$instances[$class] = new $class();
return static::$instances[$class];
}
}
这样的代码:
<?php
class C1 extends Singleton { }
class C2 extends Singleton { }
C1::getInstance(); // Created C1 class
C2::getInstance(); // Still get C1 class, get_called_class() return C1 when i try get C2
我做错了什么?
答案 0 :(得分:2)
这不起作用的原因是您没有为每个子类创建$ instance属性。虽然使用static ::和get_called_class()将访问子类成员而不是超类成员,但如果子类中不存在成员,那么它们将回退到超类中定义的成员。结果是,无论如何你最终都会获得相同的成员。
尝试定义这样的子类。
class C1 extends Singleton {
protected static $instances;
}
class C2 extends Singleton {
protected static $instances;
}
答案 1 :(得分:1)
试试这个抽象的Singleton:
abstract class Singleton
{
private static $_instances = array();
public static function getInstance()
{
$class = get_called_class();
if (!isset(self::$_instances[$class])) {
self::$_instances[$class] = new $class();
}
return self::$_instances[$class];
}
}
答案 2 :(得分:1)
C1->getInstance();
C2->getInstance();
应该是
C1::getInstance();
C2::getInstance();
<强>更新强> 您不需要一个数组来保存实例,而是让子类保持。请尝试下面的代码。
class Singleton
{
private function __construct(){}
protected static $instance;
final public static function getInstance()
{
$class = get_called_class();
if(!static::$instance)
static::$instance = new $class();
return static::$instance;
}
}
class C1 extends Singleton {
protected static $instance;
}
class C2 extends Singleton {
protected static $instance;
}
var_dump(C1::getInstance());
var_dump(C2::getInstance());
答案 3 :(得分:0)
我无法重现您的问题:
var_dump(C1::getInstance());
var_dump(C2::getInstance());
给出:
object(C1)#1 (0) {
}
object(C2)#2 (0) {
}
如var_dump
输出所示,类型不同(C1
,然后是C2
)。请记住,您需要静态调用getInstance()
,因为它是静态函数。
如果您想在PHP中真正实现Singleton模式,那么您的抽象类缺少一些重要的方法定义,以使PHP更加精确。请参阅PatternsPHP Manual。
同样在PHP中,您通常根本不需要Singleton,而是注入依赖项,这将使您的代码更流畅。
希望这有用。
答案 4 :(得分:0)
抽象单身人士的工作版本:
abstract class Singletone {
private static $_instance = NULL;
private function __construct(){}
public static function GetInstance() {
if( !static::$_instance ) {
static::$_instance = new static();
}
return static::$_instance;
}
}
派生类必须覆盖$ _instance
class DefaultRouter extends Singletone {
protected static $_instance = NULL;
}
答案 5 :(得分:0)
没有必要重新定义子类中的静态$instance
属性,只需使用超类中定义的属性:
<?php
class Singleton
{
public static $Instance;
private function __construct() { }
public static function GetInstance() {
if(!Singleton::$Instance) {
Singleton::$Instance = new static();
}
return Singleton::$Instance;
}
}
class MyClass extends Singleton
{
public $field1;
public $field2;
public $field3;
public function __construct()
{
$this->field1 = "field1";
$this->field2 = "field2";
$this->field3 = "field3";
}
}
var_dump(Myclass::GetInstance());
?>
输出
object(MyClass)#1 (3) {
["field1"]=>
string(6) "field1"
["field2"]=>
string(6) "field2"
["field3"]=>
string(6) "field3"
}