PHP Синглтон, действующий смешно - PullRequest
1 голос
/ 18 января 2011

У меня есть следующий код:

$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 ]

2 голосов
/ 18 января 2011

См. http://socket7.net/article/php-5-static-and-inheritance.

Проблема в том, что существует только одна статическая переменная, определенная в области действия родительского класса. Чтобы создать две статические переменные, проще всего определить переменную $ _instance и метод get_instance в обоих подклассах.

Другой возможный обходной путь перечислен в комментариях к вышеприведенной статье: «передать дополнительный параметр имени класса в вызовы статического метода, сообщая методу, какой класс должен« действовать ».»

1 голос
/ 18 января 2011

Поскольку self разрешается до MySQL_Extension, я предполагаю, что у каждого класса есть этот метод (а не определяется в Extension_Abstract. Однако, где определяется self::$_instance? Мой инстинкт заключается в том, что он определен Extension_Abstract. Просто переопределите его в каждом классе (protected static $_instance = null;).

Кроме того, вместо self, если вы используете 5.3+, вы должны использовать static, поскольку он позволяет вам наследовать и использовать позднюю статическую привязку для определения класса.

Если это не поможет, опубликуйте больше кода (определения классов помогут) ...

0 голосов
/ 18 января 2011

поздний переплёт.

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

    return static::$_instance;
}
0 голосов
/ 18 января 2011

Попробуйте не использовать self::, но MySQL_Extension:: и Error_Extension:: явно.

Кроме того, абстрактный родительский класс Extension_Abstract не должен содержать реализацию метода getInstance.

0 голосов
/ 18 января 2011

Является ли $_instance в базовом классе?

Если это так, то у вас есть единое целое для всей иерархии, а не для каждого конкретного подкласса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...