48

When using call_user_func_array() I want to pass a parameter by reference. How would I do this. For example

function toBeCalled( &$parameter ) {
    //...Do Something...
}

$changingVar = 'passThis';
$parameters = array( $changingVar );
call_user_func_array( 'toBeCalled', $parameters );
Steven Oxley
  • 6,563
  • 6
  • 43
  • 55

4 Answers4

56

To pass by reference using call_user_func_array(), the parameter in the array must be a reference - it does not depend on the function definition whether or not it is passed by reference. For example, this would work:

function toBeCalled( &$parameter ) {
    //...Do Something...
}

$changingVar = 'passThis';
$parameters = array( &$changingVar );
call_user_func_array( 'toBeCalled', $parameters );

See the notes on the call_user_func_array() function documentation for more information.

Steven Oxley
  • 6,563
  • 6
  • 43
  • 55
  • 10
    This solution throws warning with STRICT enabled... "Deprecated: Call-time pass-by-reference has been deprecated in" – Archenoth Mar 17 '13 at 20:51
  • 3
    I don't know about newer version of php but on my 5.3.3 server when i used `call_user_func("function", &$parameter)` I got the Deprecated message. When i switched to `call_user_func_array` it fixed the issue. So then i checked with STRICT enabled and still didn't get the message so i think this is an acceptable way to do it. – Lightbulb1 Jul 11 '14 at 15:51
  • I made a code test, and I works for me from php 4.3.0 - 7.4.0 even if I enable STRICT. @see https://3v4l.org/NJN2u to see by yourself – Radon8472 Dec 07 '19 at 13:08
1

Directly, it may be impossible -- however, if you have control both over the function you are implementing and of the code that calls it - then there is one work-around that you might find suitable.

Would you be okay with having to embed the variable in question into an object? The code would look (somewhat) like this if you did so.

function toBeCalled( $par_ref ) {
    $parameter = $par_ref->parameter;
    //...Do Something...
    $par_ref->parameter = $parameter;
}

$changingVar = 'passThis';
$parembed = new stdClass; // Creates an empty object
$parembed->parameter = array( $changingVar );
call_user_func_array( 'toBeCalled', $parembed );

You see, an object variable in PHP is merely a reference to the contents of the object --- so if you pass an object to a function, any changes that the function makes to the content of the object will be reflected in what the calling function has access to as well.

Just make sure that the calling function never does an assignment to the object variable itself - or that will cause the function to, basically, lose the reference. Any assignment statement the function makes must be strictly to the contents of the object.

Sophia_ES
  • 1,193
  • 3
  • 12
  • 22
0

This works by double referencing,the original variable is modified when the $parameter variable is modified.

$a = 2;
$a = toBeCalled($a);
echo $a //50

function toBeCalled( &$par_ref ) {
    $parameter = &$par_ref;
    $parameter = $parameter*25;
}
Manoj Sharma
  • 1,467
  • 2
  • 13
  • 20
Danny
  • 1
-2

Except you are using deprecated functionality here. You'll generate a warning in PHP5 making it less than perfect.

Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of runtime function name. If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file in ...

Unfortunately, there doesn't appear to be any other option as far as I can discover.

voidstate
  • 7,937
  • 4
  • 40
  • 52
  • 6
    I just tried doing this with PHP 5.2.9 and didn't get any warnings. I think you might be confused by the fact that array() isn't really a function - what I'm doing in my code example is basically setting `$parameters[0] =& $changingVar`. Therefore, it's not call-time pass-by-reference - the pass-by-reference is specified in the method signature. – Steven Oxley Sep 09 '09 at 23:08
  • 1
    That only applies to direct function calls. `array()` isn't a function. As of PHP 5.5, it's quite normal to put references in arrays. – Zenexer Apr 15 '14 at 05:27
  • Keep in mind that passing `new` by reference is deprecated with PHP 5.5(?), so `$foo =& new ReferenceObject` isn't allowed anymore. – kaiser Dec 19 '14 at 09:53