Home » Php » php – Why does the error "expected to be a reference, value given" appear?

php – Why does the error "expected to be a reference, value given" appear?

Posted by: admin April 23, 2020 Leave a comment

Questions:

It fires out when I try to call function with argument by reference

function test(&$a) ...

through

call_user_func('test', $b);
How to&Answers:

call_user_func can only pass parameters by value, not by reference. If you want to pass by reference, you need to call the function directly, or use call_user_func_array, which accepts references (however this may not work in PHP 5.3 and beyond, depending on what part of the manual look at).

Answer:

From the manual for call_user_func()

Note that the parameters for call_user_func() are not passed by reference.

So yea, there is your answer. However, there is a way around it, again reading through the manual

call_user_func_array('test', array(&$b));

Should be able to pass it by reference.

Answer:

I’ve just had the same problem, changing (in my case):

$result = call_user_func($this->_eventHandler[$handlerName][$i], $this, $event);

to

$result = call_user_func($this->_eventHandler[$handlerName][$i], &$this, &$event);

seem to work just fine in php 5.3.

It’s not even a workaround I think, it’s just doing what is told 🙂

Answer:

You need to set the variable equal to the result of the function, like so…

$b = call_user_func('test', $b);

and the function should be written as follows…

function test($a) {
    ...
    return $a
}

The other pass by reference work-a-rounds are deprecated.

Answer:

You might consider the closure concept with a reference variable tucked into the “use” declaration. For example:

$note = 'before';
$cbl = function( $msg ) use ( &$note )
{
    echo "Inside callable with $note and $msg\n";
    $note = "$msg has been noted";
};
call_user_func( $cbl, 'after' );
echo "$note\n";

Bit of a workaround for your original problem but if you have a function that needs call by reference, you can wrap a callable closure around it, and then execute the closure via call_user_func().