spyro95
spyro95

Reputation: 146

Get called function from parent __construct

is there any smart solution to get the called method from parents __construct?

example:

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

I want to know that $indexMethod got called, but I try to get this information while I am in $parentController __construct.

I know that I can get the classname with

get_called_class()

or via ReflectionClass, but is there any solution for the called method?

Already tried

debug_backtrace()

but I can only obtain any information about the other direction.

Edit:

Anyone is calling my website: https://example.com/index/firstaction

Then the router is searching for the controller: indexcontroller and method: firstaction.

The indexcontroller extends the class ParentController.

Now I want to get the name of the called method(firstaction) in the parent(ParentController) of indexcontroller

class ParentController {

public function __construct() 
{
}

Upvotes: 0

Views: 155

Answers (1)

ArtisticPhoenix
ArtisticPhoenix

Reputation: 21671

The only way I can think of (not that it's proper OOP principal)

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();

Output

notset
set

This is where I point out it's not important where these are called from. Basically you just need to set some property shared by the parent to maintain the state of if that call was made to the class.

One other Glaring issue is this call

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

Where do you get this from $childrenController. I am assuming you would only use parent::__construct() in the child's constructor. If that is the case, then you won't have "time" to call_user_func_array with its instance (unless from the constructor of the child), because you don't get that instance (outside the class) to use tell after running construction to completion. For example

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

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

Essentially you have to call public function indexMethod before construction ends in order to access that in parent::__construct if used in the typical way (called in child construct). So you have a very tiny window you can do this in, inside the child's constructor.

That said this is not the case with other methods, construct is a special case. Maybe you can do static to get around that issue... etc. I don't know.

One last note

This is probably wrong from an OOP principal standpoint as now the Parent class has a hidden dependency on one of the children classes. I am sure it violates S.O.L.I.D -

want to tell smarty the directory for the templates dynamically by passing the foldername(called class) and filename(called method). So I thought the best solution would be to do that in ParentController from which any controller inherits

Why not just pass it though the child to the parent:

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

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

Now you can set foo to your hearts content.

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

I don't think you need any special triks, if you just want to register a piece of info in the parent class. Especially when your writing that class, just add it like any old property.

Cheers!

Upvotes: 1

Related Questions