Позднее статическое связывание PHP в синглтоне - PullRequest
1 голос
/ 01 марта 2011

У меня есть этот код из какой-то статьи на 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;

}

Но я не могу понять главное различие между «static» и «self» в этом случае: например, если мы определим $ _instances как public и попытаемся создать какой-то другой класс, такой как

class C extends Singleton {

    private $_z =  55;

}

и определяем Singleton как не абстрактный класс, после каждого вызова getInstance у нас есть одинаковый массив экземпляров в обоих случаях: со статическими :: $ _ экземплярами и self :: $ _ экземплярами:

$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 одинаковы и почему автор использует static, а не self? Большое спасибо, извините за мой английский.

1 Ответ

2 голосов
/ 02 марта 2011

Все классы имеют один и тот же статический массив $ _instances, содержащийся в классе Singleton. Причина, по которой автор использовал «новую статичность»; должен был сохранить объект вызываемого класса в этом массиве. Поскольку существует только один массив, вызовы self :: и static :: для этого массива из класса Singleton будут возвращать те же данные.

Итак, чтобы уточнить, когда вы звоните:

$b_instance = B::getInstance();

экземпляр B добавляется в массив $ _instances, хранящийся в Singleton. Если вы добавите статическое свойство $ _instances в класс B или C, поведение будет другим, в том смысле, что вновь созданный экземпляр будет храниться в собственном свойстве класса static $ _instances.

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