Page 1 of 1

call_user_func_array() and inheritance

Posted: Mon Aug 20, 2007 5:31 pm
by smudge
Hello, I'm working on a simple framework, and the way I'm doing controllers is this:
DefaultController.php:

Code: Select all

class DefaultController extends Controller
{
  public function index(){
    $this->_display();
  }
}
Controller.php:

Code: Select all

class Controller
{
  function init($name,$action='index',$params=array()){
    call_user_func_array($action,$params);
  }
  ...
}
Now, when I do this:

Code: Select all

$class=new DefaultController;
$class->init('DefaultController','index');
It says that the first argument of call_user_func_array() is supposed to be a valid callback, and 'index' is not.
I'm almost certain this has to do with the fact that index() was not defined in the parent class. How do I fix/get around this?

Posted: Mon Aug 20, 2007 5:40 pm
by feyd
If memory serves me, you cannot call a child's methods unless they are overloads of the parent's methods (in the scope of the parent.) The child can call any of its methods and the parent's methods however.

Posted: Mon Aug 20, 2007 6:08 pm
by smudge
So how would you recommend I get around this? I've been trying to wrap my head around this for 20 minutes now, and can't come up with a good solution.

Posted: Mon Aug 20, 2007 6:12 pm
by volka
For object method calls you have to provide the object context, in this case $this.

Code: Select all

<?php
class Controller
{
  function init($name,$action='index',$params=array()){
    call_user_func_array(array($this,$action),$params);
  }
}

class DefaultController extends Controller
{
  public function index(){
    $this->_display();
  }
  
  protected function _display() {
  	echo __METHOD__;
  }
}

$class=new DefaultController;
$class->init('DefaultController','index');
But why don't you just override init($params) in DefaultController ?

Posted: Mon Aug 20, 2007 6:38 pm
by smudge
DefaultController is the controller I'm using as a (for lack of better term) default controller. Being a framework, there will be other controllers like it, and it seems 'unclean' to have to override init() in each new controller. Besides that, I have seen other frameworks where this is not necessary.

Posted: Mon Aug 20, 2007 6:47 pm
by volka
And calling some arbitrary method with arbitrary parameters is cleaner?
I don't think so but that's something for Theory and Design (which for me translates to: Have it your way ;)).

Posted: Mon Aug 20, 2007 7:06 pm
by smudge
Thanks a lot, that worked, but what do you mean by an arbitrary method with arbitrary parameters?

Posted: Mon Aug 20, 2007 9:58 pm
by superdezign
smudge wrote:Thanks a lot, that worked, but what do you mean by an arbitrary method with arbitrary parameters?
It's extremely generic. In my opinion, too much so. There's nothing wrong with overloading a method.

Posted: Tue Aug 21, 2007 8:09 am
by smudge
If you are talking about init(), I see what you mean. I just designed it that way because of flexibility within the framework.
So far, I haven't gotten mod_rewrite to work, so routes are presented as framework/index.php/controller/action/param/param/...
There must be a controller, action may or may not exist, and there are any number of params, so I designed init() that way. The real init (not what I showed here) assigns the arguments to properties which are stored for use by other methods such as _display(), which require()s views/$name/$action.php
So far everything in the framework generally works except for a few bugs. Maybe when I'm finally done I'll put in critique...