12

Is there any way, in PHP, to call methods from a parent class using the arbitrary-argument call_user_func_array? Essentially, I want to write a little bit of boilerplate code that, while slightly less optimal, will let me invoke the parent to a method arbitrarily like this:

function childFunction($arg1, $arg2, $arg3 = null) {
    // I do other things to override the parent here...

    $args = func_get_args();
    call_user_func_array(array(parent, __FUNCTION__), $args); // how can I do this?
}

Is this an odd hack? Yeah. I will be using this boilerplate in many places, though, where there's likely to be error in transcribing the method args properly, so the tradeoff is for fewer bugs overall.

1
  • I would bet that a construction like this would be more likely to cause bugs, because call_user_func_array and friends are somewhat magical. Something tells me there is probably a better solution, but the problem isn't clear enough to me to see it. Commented Jun 22, 2010 at 18:29

2 Answers 2

31

Try either one of

call_user_func_array(array($this, 'parent::' . __FUNCTION__), $args);

or

call_user_func_array(array('parent', __FUNCTION__), $args);

... depending on your PHP version. Older ones tend to crash slightly, careful :)

Sign up to request clarification or add additional context in comments.

3 Comments

First method (array($this, 'parent::' . __FUNCTION__)) will lead to infinite recursion if you extend from class where you use call_user_func_array to call parent. Use second method, it works ok.
As of PHP 8.2, both will throw a deprecated notice
-3

You can call any method on a parent class, as long as it is not overloaded closer to the class of the instance. Just use $this->methodName(...)

For slightly more advanced magic, here's a working example of what you seem to want:

Please note that i do not believe this to be a good idea

class MathStuff
{
    public function multiply()
    {
        $total = 1;
        $args = func_get_args();
        foreach($args as $order => $arg)
        {
            $total = $total * $arg;
        }
        return $total;
    }
}
class DangerousCode extends MathStuff
{
    public function multiply()
    {
        $args = func_get_args();

        $reflector = new ReflectionClass(get_class($this));
        $parent = $reflector->getParentClass();
        $method = $parent->getMethod('multiply');
        return $method->invokeArgs($this, $args);
    }
}


$danger = new DangerousCode();
echo $danger->multiply(10, 20, 30, 40);

Basically, this looks up the method MathStuff::multiply in the method lookup table, and executes its code on instance data from a DangerousCode instance.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.