Bug #72326 [Opn->Ver]: Closure::call does not allow closure to accept arguments by reference
| From: | cmb@php.net | Date: | Wed, 01 Dec 2021 16:09:31 +0000 |
| Subject: | Bug #72326 [Opn->Ver]: Closure::call does not allow closure to accept arguments by reference | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-238095@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=72326&edit=1
ID: 72326
Updated by: cmb@php.net
Reported by: contact at jaborandi dot org dot ru
Summary: Closure::call does not allow closure to accept
arguments by reference
-Status: Open
+Status: Verified
Type: Bug
Package: Variables related
PHP Version: 7.0.7
Block user comment: N
Private report: N
New Comment:
Confirmed: <https://3v4l.org/SPse9>. Since there are
viable
workarounds available, that might be a documentation problem.
Previous Comments:
------------------------------------------------------------------------
[2016-06-03 18:07:35] contact at jaborandi dot org dot ru
A misinformation in my original post, call_user_func does not (always) work.
It works only if function was called in a regular way first (something having to do with internal
caching I guess?), which was done in my test.
Here's a corrected sample code:
---------------------
$a = function(&$arg) { echo "\nok"; if (isset($this)) echo ',
'.get_class($this); echo "\n"; };
$x = 1;
$y = 1;
$a($x); // ok
call_user_func($a, $x); // ok - because $a($x) was previously called
call_user_func($a, $y); // WARNING - because $a($y) was not called
class MyContext {}
$a->call(new MyContext, $x); // WARNING
$a = Closure::bind($a, new MyContext); // workaround
$a($y); // ok, and in desired context
------------------------------------------------------------------------
[2016-06-03 18:02:50] contact at jaborandi dot org dot ru
Obvious workaround, (which I have successfully missed at first, hence this bug report), is to use
Closure::bind and then call the function in a regular way.
------------------------------------------------------------------------
[2016-06-03 10:51:45] contact at jaborandi dot org dot ru
Extra test code, to compare with cases when works:
$a = function($arg) { echo "\nok"; };
$aRef = function(&$arg) { echo "\nok"; };
$z = 1;
$a($z); // ok
$aRef($z); // ok
call_user_func($a, $z); // ok
call_user_func($aRef, $z); // ok
class MyContext {}
$a->call(new MyContext, $z); // ok
$aRef->call(new MyContext, $z); // WARNING ...
Expected:
ok
ok
ok
ok
ok
ok
Actual:
ok
ok
ok
ok
ok
Warning: Parameter 1 to MyContext::{closure}() expected to be a reference, value given in
C:\bin\php7.0.7\bug.php on line 17
------------------------------------------------------------------------
[2016-06-03 10:47:20] contact at jaborandi dot org dot ru
Description:
------------
calling Closure::call() method on anonymouse function that accepts arguments by reference triggers
Warning and doesn't execute the function
if same closure is called in regular way, or using call_user_func, or if it does not accept any
argument by reference, it is executed normally
tested in 7.0.7, as well as in 7.0.3, 7.0.4, 7.0.5, with the same result
(haven't tested call_user_func in 7.0.5 though, sandbox disabled it)
Test script:
---------------
$a = function(&$arg) { echo "ok"; };
$z = 1;
class MyContext {}
$a->call(new MyContext, $z);
Expected result:
----------------
ok
Actual result:
--------------
Warning: Parameter 1 to MyContext::{closure}() expected to be a reference, value given in
C:\bin\php7.0.7\bug.php on line 6
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=72326&edit=1