php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #50230 References passed to closures as variables corrupt original passed variable
Submitted: 2009-11-19 13:10 UTC Modified: 2011-06-03 23:07 UTC
Votes:5
Avg. Score:4.6 ± 0.5
Reproduced:5 of 5 (100.0%)
Same Version:3 (60.0%)
Same OS:3 (60.0%)
From: ninzya at inbox dot lv Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.3, 6 OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: ninzya at inbox dot lv
New email:
PHP Version: OS:

 

 [2009-11-19 13:10 UTC] ninzya at inbox dot lv
Description:
------------
See the reproduce code. I have a variable $ref, which is a reference to another variable. I am passing $ref to closure as use() by value, but, this kind of passing corrupts $ref variable after definition of closure and $ref becomes no longer reference, but points directly to copied data of $source variable, which $ref was previously referring to. However, if i define closure the following way:

$closure =function() use( &$ref) {// note pass-by-reference
  echo $ref;
};

the $ref does not loose it's state.

Reproduce code:
---------------
$source ='Dmitry';
$ref =&$source;

$closure =function() use( $ref) {
  echo $ref;
};

$ref ='Dmitry2';

echo $ref ."\n";
echo $source ."\n";

Expected result:
----------------
Dmitry2
Dmitry2

Actual result:
--------------
Dmitry2
Dmitry

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-12-10 08:01 UTC] arpad@php.net
The problem is the data pointer from the hash apply being overwritten in zval_copy_static_var() (Zend/zend_closures.c).

The following patch works for me:

http://spellign.com/patches/php-closure-ref-HEAD.patch
 [2010-05-28 21:52 UTC] dchurch at sciencelogic dot com
I feel that this is probably the same problem:

$array = array(1,4,2,3);
usort($array, function($a,$b) use ($array) {
  return $a > $b ? 1 : -1;
});

Result is that $array is not changed by the usort function.
 [2011-06-03 07:44 UTC] arpad@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: arpad
 [2011-06-03 07:44 UTC] arpad@php.net
Thank you for your bug report. This issue has already been fixed
in the latest released version of PHP, which you can download at 
http://www.php.net/downloads.php

Fixed by r308320 which is in 5.3.6
 [2011-06-03 23:06 UTC] derick@php.net
-Assigned To: arpad +Assigned To: derick
 [2011-06-03 23:07 UTC] derick@php.net
-Assigned To: derick +Assigned To: dmitry
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Mon Apr 28 08:01:28 2025 UTC