PHP单例与继承

PHP单例与继承,php,class,inheritance,static,singleton,Php,Class,Inheritance,Static,Singleton,我在PHP继承方面遇到了一些问题。交易如下: 我有一个基类,Singleton: namespace My_Namespace; abstract class Singleton { protected static $instance = null; static function get() { if ( null == static::$instance ) { static::$instance = new static;

我在PHP继承方面遇到了一些问题。交易如下:

我有一个基类,Singleton:

namespace My_Namespace;

abstract class Singleton {
    protected static $instance = null;

    static function get() {
        if ( null == static::$instance ) {
            static::$instance = new static;
        }
        return static::$instance;
    }

    private function __construct() {

    }
}
我有很多类继承了这个单例类,称它们为a、B、C、D。其中一个看起来像这样:

namespace My_Namespace;

class A extends Singleton {

    protected function __construct() {

        B::get();

        if ( some_condition() ) {
            C::get();
        }
        else {
            D::get();
        }
    }
}
现在,我只需要做一个
a::get()
就可以了。如预期的那样,将调用的构造函数。然后,调用B的构造函数,同样没有问题。现在它变得奇怪了。一旦调用了
C::get()
,它就会将
静态::$instance
识别为类B的对象,并且根本不实例化C。我知道如果我有点像菊花链,那就是B调用的
\uu构造
C::get
D::get
它可以工作,但这对我来说不是最佳的。这是因为它们在同一范围内吗?如果是的话,有什么办法可以解决这个问题吗?我问这个问题更多的是出于好奇,而不是出于实际目的——我知道我可以很容易地在它们中的每一个中实现单例模式。有什么想法吗?谢谢


另外,请不要评论“单身是邪恶的,你应该在地狱里烧掉”。我非常清楚。

注意,
静态::$instance=new static
调用(在您的例子中)A的构造函数

对于您的解决方案,您将需要子类中的实例的静态属性

加上

protected static $instance = null;

对他们来说,这应该很好

在处理静态属性时,如果希望继承类的静态属性与基类不同,则必须为其提供一个居住环境

要解决这个问题,只需定义

protected static $instance = null;

在派生类上。如果不是,它将使用基类的属性

+1表示<代码>否。。。burn in hell comments
我相信继承的类需要一个静态属性,以便将实例推入。。。因此添加
受保护的静态$instance=null到子类。@Orangepill您会得到它的。我添加了这一行,一切正常<代码>但是:
这使得整个单例类和继承的东西都没用了。。。其想法是将单例功能封装在该类中。那有可能吗?没有。。。如果您没有一个属性来将其塞入,它将返回到继承的属性,在静态意义上,继承的属性是基类属性:(为什么它在前两次工作?如果我不在同一个范围内,比如在
A::get()
B::get()
中,它会创建适当的实例,但只要它点击
C::get())
它又回到了它用于
B::get
?这有什么意义吗?它在前两次不起作用,第一次起作用。你调用
A::get()
。然后调用
A
的构造函数。调用
B::get()
,然后从基类设置
$instance
(第一次设置时)。现在您要调用
C::get()
,它检查
null==static::$instance
,但是现在
$instance
(来自类A)已经是一个对象。我花了一段时间才意识到解释是多么简单。在那
静态::$instance=new static
,调用构造函数,调用另一个构造函数,所有这些都是在将任何内容赋给实际的$instance变量之前调用的,因为它还没有返回ed。我真傻。谢谢你的回答。没问题,顺便说一句:也许你应该这样做另外,将
最终私有函数uu clone(){}
放在您的单例中,以防止对象克隆