php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #70379 call_user_func_array only accepts explicit references
Submitted: 2015-08-28 09:00 UTC Modified: 2015-08-30 13:54 UTC
Votes:5
Avg. Score:3.4 ± 0.5
Reproduced:3 of 3 (100.0%)
Same Version:2 (66.7%)
Same OS:1 (33.3%)
From: lolautruche at gmail dot com Assigned:
Status: Analyzed Package: Unknown/Other Function
PHP Version: 7.0.0RC1 OS: OSX
Private report: No CVE-ID: None
 [2015-08-28 09:00 UTC] lolautruche at gmail dot com
Description:
------------
In PHP 7, passing variables assigned by reference to call_user_func_array() (as part of arguments) now triggers a warning :

"Warning: Parameter 1 to ... expected to be a reference, value given in..."

It worked fine in PHP 5.6.
Current workaround is to explicitly pass the value by reference (see code).

Not sure if this is on purpose, but I couldn't find any mention in the UPGRADING doc about this specifically.

Test script:
---------------
<?php
$foo = function (&$arg) {
    var_dump($arg);
};

$a = 'bar';
$b =& $a;

// Warning: Parameter 1 to {closure}() expected to be a reference, value given in /Users/lolautruche/Desktop/reference.php on line 8
call_user_func_array($foo, [$b]);

// Works fine
call_user_func_array($foo, [&$a]);


Expected result:
----------------
string(3) "bar"
string(3) "bar"

Actual result:
--------------
Warning: Parameter 1 to {closure}() expected to be a reference, value given in /Users/lolautruche/Desktop/reference.php on line 10
string(3) "bar"


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-08-28 13:14 UTC] laruence@php.net
-Assigned To: +Assigned To: laruence
 [2015-08-29 04:28 UTC] patrickallaert@php.net
Thinking about this, the behavior of PHP 5.x is strange.

When a function accepts a value by reference, the only check should be to ensure that a variable is passed, otherwise "Fatal error:  Only variables can be passed by reference" should be raised, e.g.:

function by_ref(&$arg) {
    $arg = "changed";
};

by_ref("foo"); // Triggers the fatal error

$x = "orig";
by_ref($x); // Changes $x to "changed"

A function using "value by reference" doesn't mean that a reference should be passed on but that the local variable to the function should be treated as a reference to the original one.

Hence I think that in ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt, the second test: "Calling by_ref() with unreferenced argument" should NOT emit the warning "Warning: Parameter 1 to by_ref() expected to be a reference" either.

Note that in PHP 5, one can call:
call_user_func_array("by_ref", ["test"]);

This is inconsistent as well, "Fatal error:  Only variables can be passed by reference" should have been triggered.
 [2015-08-30 03:12 UTC] laruence@php.net
actually, this is a knew issue(bc break), anyway, it's not possible to fix this to behavior exactly the same as 5.6

and I also think the current behavior is more reasonable
 [2015-08-30 06:31 UTC] lolautruche at gmail dot com
OK, but it should at least be documented IMHO, both in the upgrade doc and on the function changelog.
 [2015-08-30 08:04 UTC] laruence@php.net
-Type: Bug +Type: Documentation Problem -Assigned To: laruence +Assigned To:
 [2015-08-30 08:04 UTC] laruence@php.net
of course, change to doc bug..
 [2015-08-30 13:54 UTC] laruence@php.net
-Status: Open +Status: Analyzed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Nov 25 06:01:32 2024 UTC