php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #43079 call_user_func_array(): documentation for pass-by-value/pass-by-ref behaviour
Submitted: 2007-10-23 09:34 UTC Modified: 2007-11-21 14:42 UTC
From: robin_fernandes at uk dot ibm dot com Assigned:
Status: Closed Package: Documentation problem
PHP Version: Irrelevant OS: Windows
Private report: No CVE-ID: None
 [2007-10-23 09:34 UTC] robin_fernandes at uk dot ibm dot com
Description:
------------
The documentation for call_user_func_array() makes no mention of pass-by-value / pass-by-reference (unlike call_user_func(), which is very clear on this subject).

This is significant because the behaviour of call_user_func_array() is not intuitive (see the user contributed notes on the documentation page: http://php.net/call_user_func_array ).

It appears that the way in which an argument is passed depends not on the target function signature, but rather on whether its entry in $param_arr is referenced or not.

Specifically, it is possible to force an argument to be passed by reference to a function which expects a pass-by-value argument, even with call time pass by reference DISABLED in php.ini.

See the reproduce code snippet for an example.

The most succinct way I'm able to express this is:
  "Regardless of the callback function's signature, any member of $param_arr that is referenced will be passed by reference and any member that is not reference will be passed by value."

I'm assuming this behaviour is intentional. If not I'll happily raise a scripting engine bug - let me know.

Reproduce code:
---------------
<?php
 function byRef(&$a, &$b) {
 	$a = 'changed';
 	$b = 'changed.b';
 }
 
 function byVal($a, $b) {
 	$a = 'changed.a';
 	$b = 'changed.b';
 }

 echo "\nForce a pass-by-reference function to take args by value:\n";
 $args = array('original.a', 'original.b');
 call_user_func_array('byRef', $args);
 var_dump($args);
 
 echo "\nForce a pass-by-Value function to take one arg by reference:\n";
 echo "NOTE: this works even with call time pass by reference DISABLED in php.ini:\n";
 $args = array('original.a', 'original.b');
 $ref = &$args[0];
 call_user_func_array('byVal', $args);
 var_dump($args); 
?>

Expected result:
----------------
Force a pass-by-reference function to take args by value:
array(2) {
  [0]=>
  string(10) "original.a"
  [1]=>
  string(10) "original.b"
}

Force a pass-by-Value function to take one arg by reference:
NOTE: this works even with call time pass by reference DISABLED in php.ini:
array(2) {
  [0]=>
  &string(9) "changed.a"
  [1]=>
  string(10) "original.b"
}

Actual result:
--------------
N/A

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-11-21 14:42 UTC] vrana@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.

"Referenced variables in param_arr are passed to the function by a reference, others are passed by a value. In other words, it does not depend on the function signature whether the parameter is passed by a value or by a reference."

This behavior is however wrong and can be even dangerous. So please report new Scripting Engine problem with reference to this bug.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon May 13 14:01:33 2024 UTC