Передача данных в уже созданый объект? Иллюстрирую такой код для примера, который состоит из 5 классов. - Класс Chief создает и возвращает объекты и имеет четыре наследника. - Класс библиотеки Library с различными методами и свойствами, которые доступные для использования всеми последующими; - Два класса модулей Module и один View - выводит общую картину.error_reporting(E_ALL); class Chief { private static $obs = array(); private $classes = array( 'lib' => 'Library', 'mod1' => 'Module1', 'mod2' => 'Module2', 'view' => 'View', );
public function __get($name) { // Определение имени классов в которых вызываются не определенные свойства $descendantClassName = get_class($this); echo $descendantClassName . '';
// Если объект уже существует, возвращаем его if(isset(self::$obs[$name])) { return(self::$obs[$name]); } // Определяем имя нужного класса $class = $this->classes[$name];
// Сохраняем для будущих обращений к нему self::$obs[$name] = new $class();
// Возвращаем созданный объект return self::$obs[$name]; } } class Library extends Chief { // Свойства и методы библиотеки выполняющие что-либо, созданные для примера
public $prop_1; public $prop_2; public $prop_3;
public function __construct(){}
public function toolA(){}
public function toolB(){}
public function toolC(){} } class Module1 extends Chief { public function perf() { $this->lib->toolA(); $m2 = new Module2(); return $this->lib->prop_3 = $m2->perf(); } } class Module2 extends Chief { public function perf() { return $this->lib->toolC(); } } class View extends Chief { public function perf(){
$this->lib->toolB(); $content = new Module1(); $content->perf(); $this->lib->prop_1; } } $res = new View(); print $res->perf();Вопрос: нужно предавать объекту класса Library информацию о том в которых классах осуществляется его вызов, то есть переменную $descendantClassName. Можно было б передать это параметром в конструкторе self::$obs[$name] = new $class($descendantClassName) и при создании объекта $this->lib использовать эту инфу. Но это возможно только 1 раз, при дальнейших вызовах объекта $this->lib он просто возвращается из массива с первоначально заложенным значением переменой $descendantClassName. Как тогда передавать классу Library постоянно меняющиеся данные из переменной $descendantClassName если возвращается уже созданный объект.
В данном случае можно создать метод в классе Chief, который будет обновлять информацию о том, в каком классе происходит вызов объекта Library. Например, можно добавить метод setDescendantClassName($className) в класс Chief, который будет обновлять значение переменной $descendantClassName. Затем этот метод можно вызывать перед каждым использованием объекта Library в дочерних классах:
class Chief { private static $obs = array(); private $classes = array( 'lib' => 'Library', 'mod1' => 'Module1', 'mod2' => 'Module2', 'view' => 'View', ); private $descendantClassName; public function __get($name) { // Если объект уже существует, возвращаем его if(isset(self::$obs[$name])) { return(self::$obs[$name]); } // Определяем имя нужного класса $class = $this->classes[$name]; // Сохраняем для будущих обращений к нему self::$obs[$name] = new $class(); // Устанавливаем значение переменной $descendantClassName self::$obs[$name]->setDescendantClassName($this->descendantClassName); // Возвращаем созданный объект return self::$obs[$name]; } public function setDescendantClassName($className) { $this->descendantClassName = $className; } } class Library extends Chief { // Свойства и методы библиотеки private $descendantClassName; public function setDescendantClassName($className) { $this->descendantClassName = $className; } // Ваши методы } class Module1 extends Chief { public function perf() { $this->lib->setDescendantClassName(get_class($this)); $this->lib->toolA(); $m2 = new Module2(); return $this->lib->prop_3 = $m2->perf(); } } // Аналогично для других дочерних классов $res = new View(); $res->perf();
Таким образом, вы сможете передавать классу Library информацию о текущем классе, в котором происходит вызов объекта, перед каждым использованием этого объекта из дочерних классов.
В данном случае можно создать метод в классе Chief, который будет обновлять информацию о том, в каком классе происходит вызов объекта Library. Например, можно добавить метод setDescendantClassName($className) в класс Chief, который будет обновлять значение переменной $descendantClassName. Затем этот метод можно вызывать перед каждым использованием объекта Library в дочерних классах:
class Chief{
private static $obs = array();
private $classes = array(
'lib' => 'Library',
'mod1' => 'Module1',
'mod2' => 'Module2',
'view' => 'View',
);
private $descendantClassName;
public function __get($name)
{
// Если объект уже существует, возвращаем его
if(isset(self::$obs[$name]))
{
return(self::$obs[$name]);
}
// Определяем имя нужного класса
$class = $this->classes[$name];
// Сохраняем для будущих обращений к нему
self::$obs[$name] = new $class();
// Устанавливаем значение переменной $descendantClassName
self::$obs[$name]->setDescendantClassName($this->descendantClassName);
// Возвращаем созданный объект
return self::$obs[$name];
}
public function setDescendantClassName($className)
{
$this->descendantClassName = $className;
}
}
class Library extends Chief
{
// Свойства и методы библиотеки
private $descendantClassName;
public function setDescendantClassName($className)
{
$this->descendantClassName = $className;
}
// Ваши методы
}
class Module1 extends Chief
{
public function perf()
{
$this->lib->setDescendantClassName(get_class($this));
$this->lib->toolA();
$m2 = new Module2();
return $this->lib->prop_3 = $m2->perf();
}
}
// Аналогично для других дочерних классов
$res = new View();
$res->perf();
Таким образом, вы сможете передавать классу Library информацию о текущем классе, в котором происходит вызов объекта, перед каждым использованием этого объекта из дочерних классов.