Прямо в точку:
У меня есть два синглтон-класса, оба унаследовали свою синглтон-природу от суперкласса. Я инициализирую некоторые свойства первого синглтона, а затем второй синглтон извлекает экземпляр первого. Этот экземпляр, однако, не похож на тот, который я изначально инициализировал. Некоторый пример кода может помочь объяснить это:
Во-первых, суперкласс, обеспечивающий одноэлементную природу (требуется PHP 5.3 или выше):
class Singleton {
protected static $instance;
protected function __construct() { }
final private function __clone() { }
public static function getInstance() {
if (!(static::$instance instanceof static)) {
static::$instance = new static();
}
return static::$instance;
}
}
Тогда у нас есть первый синглтон со значением:
require_once('Singleton.php');
class SingletonA extends Singleton {
protected $value;
public function SingletonA() {
$this->value = false;
}
public function getValue() {
return $this->value;
}
public function setValue($value) {
$this->value = $value;
}
}
Затем второй синглтон, который ссылается на первый синглтон:
require_once('Singleton.php');
require_once('SingletonA.php');
class SingletonB extends Singleton {
public function getValue() {
return SingletonA::getInstance()->getValue();
}
}
Теперь для теста, который показывает, как это не удается:
require_once('SingletonA.php');
require_once('SingletonB.php');
SingletonA::getInstance()->setValue(true);
echo (SingletonA::getInstance()->getValue()) ? "true\n" : "false\n";
echo (SingletonB::getInstance()->getValue()) ? "true\n" : "false\n";
Тест дает следующий вывод:
true
false
Ясно, что экземпляр SingletonA, на который ссылается тестовый код, - это не тот экземпляр, на который ссылается экземпляр SingletonB. Короче говоря, SingletonA не так одинок, как мне нужно. Как это возможно? И какую магию я могу использовать, чтобы исправить это поведение, дав мне настоящий синглтон?