PHP: call_user_func_array: pass by reference issue
Asked Answered
M

2

6

The below function generates error when a function contains referenced arguments eg:

function test(&$arg, &$arg2)
{
  // some code
}

Now I can not use call_user_func_array for above function, it will generate an error.

How to solve this problem?

I do need to use call_user_func_array.

Also assume that i don't know beforehand whether they are passed by reference or passed by value.

Thanks

Molten answered 15/12, 2009 at 7:44 Comment(1)
It would be worth while for you to unaccept the current answer as it is quite literally wrong (not to mention has bad advice by abusing objects which changes the semantics of the problem completely): codepad.viper-7.com/j3GOpsPuritanical
B
7

A great workaround was posted on http://www.php.net/manual/de/function.call-user-func-array.php#91503

function executeHook($name, $type='hooks'){ 
    $args = func_get_args(); 
    array_shift($args); 
    array_shift($args); 
    //Rather stupid Hack for the call_user_func_array(); 
    $Args = array(); 
    foreach($args as $k => &$arg){ 
        $Args[$k] = &$arg; 
    } 
    //End Hack 
    $hooks = &$this->$type; 
    if(!isset($hooks[$name])) return false; 
    $hook = $hooks[$name]; 
    call_user_func_array($hook, $Args); 
} 

The actual hack is surrounded by comments.

Bosnia answered 19/8, 2013 at 9:15 Comment(3)
thank you man, saved my life! this is definitely the correct answerAbigail
Spoke too soon … While this removes the error, it wouldn't let me manipulate the referenced variable inside the callable.Ellingston
For PHP 5.6 and above declare the function with , &...$args and then call the hook as simple as $hook(...$args).Haffner
J
22

When storing your parameters in the array, make sure you are storing a reference to those parameters, it should work fine.

Ie:

call_user_func_array("test", array(&param1, &param2));
Jobbery answered 15/12, 2009 at 7:47 Comment(5)
but what if i don't know beforehand whether they are passed by reference or passed by value?Molten
Then figure out a way to determine that, or make them all pass by reference would be my suggestion. Not much else you can do I'm afraid.Jobbery
Myles: what if I don't know amount of arguments in the array?Florenceflorencia
@Florenceflorencia ultimately you need an array of references. You'll be passing something so just create an array from whatever that something is.Jobbery
yes, right, seems call_user_func_array becomes useless in my case, i have to write spaghetti code instead of this switch(count($args)) { case 0: $class->{$method}(); break; case 1: }Florenceflorencia
B
7

A great workaround was posted on http://www.php.net/manual/de/function.call-user-func-array.php#91503

function executeHook($name, $type='hooks'){ 
    $args = func_get_args(); 
    array_shift($args); 
    array_shift($args); 
    //Rather stupid Hack for the call_user_func_array(); 
    $Args = array(); 
    foreach($args as $k => &$arg){ 
        $Args[$k] = &$arg; 
    } 
    //End Hack 
    $hooks = &$this->$type; 
    if(!isset($hooks[$name])) return false; 
    $hook = $hooks[$name]; 
    call_user_func_array($hook, $Args); 
} 

The actual hack is surrounded by comments.

Bosnia answered 19/8, 2013 at 9:15 Comment(3)
thank you man, saved my life! this is definitely the correct answerAbigail
Spoke too soon … While this removes the error, it wouldn't let me manipulate the referenced variable inside the callable.Ellingston
For PHP 5.6 and above declare the function with , &...$args and then call the hook as simple as $hook(...$args).Haffner

© 2022 - 2024 — McMap. All rights reserved.