【问题标题】:PHP Late Static Binding in Singleton单例中的 PHP 后期静态绑定
【发布时间】: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 数组是相同的,为什么作者使用静态而不是自我?非常感谢,对不起我的英语。

【问题讨论】:

  • 不,这不是重复的。我知道,什么是 LSB。我问了其他问题。
  • 如果您认为它不是重复的,那么请澄清问题,而不是仅仅说“不,它不是”。除了我刚刚删除的答案之外,您没有得到任何其他答案,因此要么我们所有人都很愚蠢,要么您的问题不清楚。你的选择。
  • 如果问题很严格,而不是关于“帮帮我,我不想阅读文档,LSB 是什么???77”,我不知道该如何描述问题

标签: php static late-binding


【解决方案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,然后重新运行您的示例。你应该明白我的意思了。
猜你喜欢
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
相关资源
最近更新 更多