PHP Singleton Acting Funny
I have the following code:
$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);
Each getInstance() method looks like this:
public static function getInstance()
{
if (self::$_instance == null)
{
self::$_instance = new self;
}
return self::$_instance;
}
Both classes extend the same "Extension_Abstract" class, but for some reason, the "print_r" debug statement listed outputs the following:
stdClass Object (
[MySQL] => MySQL_Extension Object
[Error] => MySQL_Extension Object
)
Do you all have any idea why it would be returning two "MySQL_Extension" objects, and completely ignoring the Error_Extension class? I'm so confused!
See http://socket7.net/article/php-5-static-and-inheritance.
The problem is there is only one static variable, defined within the scope of the parent class. To create two static variables, the easiest way is to just define $_instance variable and get_instance method in both subclasses.
Another possible workaround is listed in the comments of the above article: "pass an extra class name parameter into the static method calls telling the method which class it should 'act as.'"
Since self
is resolving to MySQL_Extension
, I'm assuming that each class has this method (rather than being defined in Extension_Abstract
. However, where is self::$_instance
defined? My instinct is that it's defined on Extension_Abstract
. Simply re-define it in each class (protected static $_instance = null;
).
Also, instead of self
, if you're using 5.3+ you should use static
since it enables you to inherit and use late-static-binding to determine the class.
If that doesn't help, post more code (the class definitions would help)...
Is $_instance
in the base class?
If so, then you've got a singleton for the entire hierarchy, not each specific subclass.
Try not using self::
, but MySQL_Extension::
and Error_Extension::
explicitly.
Also, the abstract parent class Extension_Abstract
should not contain the implementation for the getInstance
method.
late binding issue.
public static function getInstance()
{
if (static::$_instance == null)
{
static::$_instance = new static();
}
return static::$_instance;
}
精彩评论