php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79996 Reference trouble in closure
Submitted: 2020-08-19 12:30 UTC Modified: 2020-08-19 12:42 UTC
From: tropicano at ukr dot net Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 7.4.9 OS: Windows 10
Private report: No CVE-ID: None
 [2020-08-19 12:30 UTC] tropicano at ukr dot net
Description:
------------
Not correct result in closure function.
Please review and fix it.

Test script:
---------------
$x = 0;

function main($func, $func2)
{
    return $func($func2);
}

function callback_main($func3)
{
    $data = 1;
    $func3($data);
    return $data;
}

echo main('callback_main', function (&$data) use ($x)
                           {
                               $data =& $x;
                               $data = 2;
                           }
          );

Expected result:
----------------
echo is: 1


Actual result:
--------------
must be: 2

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-08-19 12:42 UTC] danack@php.net
-Status: Open +Status: Not a bug
 [2020-08-19 12:42 UTC] danack@php.net
Pretty sure your code is working correctly, just not as you expect it to.

$data =& $x;

That line makes $data be a reference to the value stored in $x which was captured by value in `use ($x)` . It breaks the reference to the value stored in `$data = 1`

I'd pretty strongly recommend not using references like this. Either use objects with clearer semantics, or just pass in and return values. Trying to manage state with references like this is confusing, as you're finding out.
 [2020-08-19 13:15 UTC] tropicano at ukr dot net
I known that it possible not good construction, my code is very hard to show bug.
But $data must be assigned value "2" or show notice/warning/error.
 [2020-08-19 13:40 UTC] danack@php.net
Pretty sure your code is the equivalent of:

$x = 0;
$data = 1;

$foo = &$data;
$foo = &$x;

$foo = 40;

echo $data;

When a value is written to $foo, it is poiting to where $x is stored.

Which means that $data still has the original value it had, and was never modified.
 [2020-08-19 14:11 UTC] tropicano at ukr dot net
Thanks!
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Mon Aug 15 01:05:44 2022 UTC