PHP Singleton表演搞笑

时间:2011-01-18 19:12:19

标签: php class object singleton

我有以下代码:

$e1 = call_user_func(array("MySQL_Extension", "getInstance"));
$e2 = call_user_func(array("Error_Extension", "getInstance"));
self::$extensions->MySQL = $e1;
self::$extensions->Error = $e2;

// Debug
echo "<pre>";
print_r(self::$extensions);

每个getInstance()方法如下所示:

public static function getInstance()
{
    if (self::$_instance == null)
    {
        self::$_instance = new self;
    }

    return self::$_instance;
}

这两个类都扩展了相同的“Extension_Abstract”类,但由于某种原因,列出的“print_r”调试语句输出如下:

stdClass Object (
    [MySQL] => MySQL_Extension Object
    [Error] => MySQL_Extension Object
)

你们都知道它为什么会返回两个“MySQL_Extension”对象,完全忽略Error_Extension类吗?我很困惑!

5 个答案:

答案 0 :(得分:2)

请参阅http://socket7.net/article/php-5-static-and-inheritance

问题是只有一个静态变量,在父类的范围内定义。要创建两个静态变量,最简单的方法是在两个子类中定义$ _instance变量和get_instance方法。

上一篇文章的评论中列出了另一种可能的解决方法:“将一个额外的类名参数传递给静态方法调用,告诉方法它应该扮演哪个类。”

答案 1 :(得分:1)

由于self正在解析为MySQL_Extension,我假设每个类都有此方法(而不是在Extension_Abstract中定义。但是,self::$_instance定义在哪里?我的直觉是它在Extension_Abstract上定义。只需在每个类中重新定义它(protected static $_instance = null;)。

此外,如果您使用的是5.3+,则应使用self而不是static,因为它可以让您继承并使用后期静态绑定来确定类。

如果这没有帮助,请发布更多代码(类定义会有所帮助)......

答案 2 :(得分:0)

基类中有$_instance吗?

如果是这样,那么你就有了整个层次结构的单例,而不是每个特定的子类。

答案 3 :(得分:0)

请勿明确使用self::MySQL_Extension::Error_Extension::

此外,抽象父类Extension_Abstract不应包含getInstance方法的实现。

答案 4 :(得分:0)

后期绑定问题。

public static function getInstance()
{
    if (static::$_instance == null)
    {
        static::$_instance = new static();
    }

    return static::$_instance;
}