views:

80

answers:

2

I found this while searching for how to fake multiple inheritance in PHP (since PHP does not support multiple inheritance directly).

http://stackoverflow.com/questions/356128/can-i-extend-a-class-using-more-than-1-class-in-php/356431#356431

Here is the complete code given there:-

class B {
    public function method_from_b($s) {
        echo $s;
    }
}

class C {
    public function method_from_c($s) {
        echo $s;
    }
}

class A extends B
{
  private $c;

  public function __construct()
  {
    $this->c = new C;
  }

  // fake "extends C" using magic function
  public function __call($method, $args)
  {
    $this->c->$method($args[0]);
  }
}


$a = new A;
$a->method_from_b("abc");
$a->method_from_c("def");

The problem
The example given here considers only one parameter for the function C::method_from_c($s). It works fine with one parameter but I have several functions of class C, some having 2, some having 3 parameters like this:-

class C {
    public function method_from_c($one,$two) {
        return $someValue;
    }

    public function another_method_from_c($one,$two, $three) {
        return $someValue;
    }
}

And I do not want to change anything in Class C's function definition (It must accept those many parameters). E.g. I do not want to use func_get_args() inside my C::method_from_c($s,$two) like this:-

public function method_from_c() 
{

     $args = func_get_args();

     //extract params from $args and then treat each parameter
}

What to do inside the __call() function of class A so that it works. I want to be able to call Class C functions like $obj->method_from_c($one,$two);

Thanks
Sandeepan

+3  A: 

you can use call_user_func_array:

function __call($method, $args) {
    call_user_func_array(array(&$this->c, $method), $args);
}

note that this won't perform as well though.

Raoul Duke
The reference operator for $this->c is redundant
symcbean
@Raoul Thanks! it worked!! Why it won't perform as well?
sandeepan
@sandeepan: actually I'm not sure, but I vaguely remember to have read somewhere that $foo->$bar() performs better than using call_user_func.
Raoul Duke
@symcbean yeah, you're right. old php4 habit :)
Raoul Duke
+1  A: 

Did you RTFM?

public function __call($method_name, $args)
{
   return call_user_method_array($method_name, $this->c, $args);
}
symcbean
Raoul Duke's answer is better than mine - (the call_user_method fns are deprecated)
symcbean
@symcbean a +1 for you too!
sandeepan