Получить вызванную функцию из родительского __construct - PullRequest
1 голос
/ 09 апреля 2019

Есть ли какое-нибудь умное решение, чтобы получить вызываемый метод от родителей __construct?

пример:

call_user_func_array([$childrenController, $indexMethod], array());

Я хочу знать, что был вызван $ indexMethod, но я пытаюсь получить эту информацию, пока я нахожусь в $ parentController __construct.

Я знаю, что могу получить имя класса с помощью

get_called_class()

или через ReflectionClass, но есть ли решение для вызываемого метода?

Уже пробовал

debug_backtrace()

но я могу получить только любую информацию о другом направлении.

Edit:

Кто-нибудь звонит на мой сайт: https://example.com/index/firstaction

Затем маршрутизатор ищет контроллер: indexcontroller и метод: firstaction.

Indexcontroller расширяет класс ParentController.

Теперь я хочу получить имя вызываемого метода (firstaction) в родительском (ParentController) indexcontroller

class ParentController {

public function __construct() 
{
}

1 Ответ

2 голосов
/ 09 апреля 2019

Единственный способ, которым я могу думать (не то, чтобы это был основной принцип ООП)

class ParentController { 
   protected $something;
   public function __construct() 
   {
         ///check if child sets this
         echo $this->something ? "set\n" : "notset\n";
   }
}
//---------------------
class ChildController0 extends ParentController{

   public function __construct() 
   {
         parent::__construct();
    }
}
//---------------------
class ChildController1 extends ParentController {

   public function __construct() 
   {
         $this->indexMethod();
         parent::__construct();
   }

   public function indexMethod(){
      $this->something = 1;
   }
}

new ChildController0();
new ChildController1();

выход

notset
set

Здесь я отмечаю, что не важно, откуда они вызываются. По сути, вам просто нужно установить какое-то свойство, совместно используемое родителем, чтобы поддерживать состояние, если этот вызов был сделан классу.

Еще один вопиющий вопрос - этот вызов

 call_user_func_array([$childrenController, $indexMethod], array());

Откуда вы это взяли $childrenController. Я предполагаю, что вы будете использовать только parent::__construct() в конструкторе ребенка. Если это так, то у вас не будет «времени» на call_user_func_array с его экземпляром (если только не из конструктора дочернего элемента), потому что вы не получите этот экземпляр (вне класса), чтобы использовать функцию Tell после выполнения строительство до завершения. Например

 $childrenController = new ChildController0();
  //__construction is finished at this point.

 call_user_func_array([$childrenController, $indexMethod], array());

По сути, вам нужно позвонить public function indexMethod до окончания строительства, чтобы получить доступ к этому в parent::__construct, если он используется обычным способом (вызывается в дочерней конструкции). Таким образом, у вас есть очень маленькое окно, в котором вы можете сделать это, внутри конструктора ребенка.

Тем не менее, это не относится к другим методам, конструкция - это особый случай. Может быть, вы можете сделать статические, чтобы обойти эту проблему ... и т. Д. Я не знаю.

Последнее примечание

Это, вероятно, неправильно с точки зрения основного ООП, поскольку теперь у класса Parent есть скрытая зависимость от одного из дочерних классов. Я уверен, что это нарушает S.O.L.I.D -

хочет динамически указать smarty каталог для шаблонов, передав имя-имя (класс) и имя файла (метод). Поэтому я подумал, что лучшим решением будет сделать это в ParentController, от которого любой контроллер наследует

Почему бы просто не передать его хотя бы ребенку родителю:

class ParentController { 
   protected $foo;
   public function __construct($foo) 
   {
        $this->setFoo($foo);
   }

   public function getFoo(){ return $this->foo; }
   public function setFoo($foo){ $this->foo = $foo; }
}

Теперь вы можете установить foo для вашего сердца.

class ChildController0 extends ParentController{
   //some piece of data only for child
   protected $bar;

   public function __construct($foo, $bar) 
   {
         parent::__construct($foo);
         $this->bar = $bar;
    }
}

$child = new ChildController0('foo'); //this->foo is 'foo'
$child->setFoo('bar'); //now its bar

Я не думаю, что вам нужны специальные трики, если вы просто хотите зарегистрировать часть информации в родительском классе. Особенно, когда вы пишете этот класс, просто добавьте его как любое старое свойство.

Ура!

...