单例中的 PHP 后期静态绑定

Posted

技术标签:

【中文标题】单例中的 PHP 后期静态绑定【英文标题】:PHP Late Static Binding in Singleton 【发布时间】:2011-03-01 08:36:27 【问题描述】:

我在 habrahabr.ru 上的一些文章中获得了这段代码:

abstract class Singleton 

    protected static $_instances = array();

    protected function __construct() 
    

    public static function getInstance() 

            $class = \get_called_class();
            if ( !isset( static::$_instances[$class] ) )
                    static::$_instances[$class] = new static;

            return static::$_instances[$class];

    

作者将其用作例如,

class B extends Singleton 

    private $_a = 10;


但在这种情况下,我无法理解“静态”和“自我”之间的主要区别:例如,如果我们将 $_instances 定义为公共并尝试创建另一个类似的类

class C extends Singleton 

    private $_z =  55;


并将 Singleton 定义为非抽象类,在每次调用 getInstance 之后,我们在两种情况下都有相同的实例数组:使用 static::$_instances 和 self::$_instances:

$s = Singleton::getInstance();

print_r(Singleton::$_instances);
print_r(B::$_instances);
print_r(C::$_instances);

$b_instance = B::getInstance();

print_r(Singleton::$_instances);
print_r(B::$_instances);
print_r(C::$_instances);

$c_instance = C::getInstance();

print_r(Singleton::$_instances);
print_r(B::$_instances);
print_r(C::$_instances);

谁能帮助我并告诉我,为什么 $_instances 数组是相同的,为什么作者使用静态而不是自我?非常感谢,对不起我的英语。

【问题讨论】:

What exactly is late-static binding in php? 的可能重复项 不,这不是重复的。我知道,什么是 LSB。我问了其他问题。 如果您认为它不是重复的,那么请澄清问题,而不是仅仅说“不,它不是”。除了我刚刚删除的答案之外,您没有得到任何其他答案,因此要么我们所有人都很愚蠢,要么您的问题不清楚。你的选择。 如果问题很严格,而不是关于“帮帮我,我不想阅读文档,LSB 是什么???77”,我不知道该如何描述问题 【参考方案1】:

所有类共享同一个静态数组 $_instances,包含在 Singleton 类中。作者使用“新静态”的原因;是将被调用类的对象存储在该数组中。因为只有一个数组,所以在 Singleton 类中调用该数组的 self:: 和 static:: 将返回相同的数据。

所以,澄清一下,当你打电话时:

$b_instance = B::getInstance();

B 的一个实例被添加到存储在 Singleton 中的 $_instances 数组中。如果您向 B 或 C 类添加静态 $_instances 属性,则行为会有所不同,因为新创建的实例将存储在其自己的类静态 $_instances 属性中。

【讨论】:

非常感谢。但是,作为最后一个问题:如果我写“static::$_instances”,PHP 在调用 B::getInstance() 时将其解释为“B 的实例数组”,还是“Singleton 的实例数组”?我认为“B 中的数组”,是吗? 不,Singleton 中的数组,因为 B 没有自己的 $_instances ...当您从 B 中调用 B::$_instances 或 static::$_instances 时,它将引用一个在辛格尔顿。只有在 B 中明确定义 $_instances 时才会有所不同。 我看不懂意识形态:“static”写在Singleton的方法中,所以当这个方法从B调用时,为什么static不引用B? 它确实引用了 B,但是因为 B 不包含 $_instances 的定义,所以它被传递给父类 Singleton。如果将 $_instances 添加到 B,那么情况会有所不同,但实际上,B 只能访问 $_instances,因为 Singleton 中有一个实例。 $_instances 的一个实例,在没有自己实例的所有子类之间共享。 添加“受保护的静态 $_instances = array();”到 B 和/或 C,然后重新运行您的示例。你应该明白我的意思了。

以上是关于单例中的 PHP 后期静态绑定的主要内容,如果未能解决你的问题,请参考以下文章

后期静态绑定在PHP中的使用

PHP中的后期静态绑定(Late Static Bindings )

PHP 5.2 等效于后期静态绑定(新静态)?

PHP中的后期静态绑定

PHP面向对象-后期静态绑定

PHP 后期静态绑定问题