Bug #74020 [Com]: Foreach-by-reference + assignment may recreate unexpected key references
| From: | icarpenter at leadid dot com | Date: | Tue, 31 Jan 2017 15:28:01 +0000 |
| Subject: | Bug #74020 [Com]: Foreach-by-reference + assignment may recreate unexpected key references | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-207071@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=74020&edit=1
ID: 74020
Comment by: icarpenter at leadid dot com
Reported by: icarpenter at leadid dot com
Summary: Foreach-by-reference + assignment may recreate
unexpected key references
Status: Verified
Type: Bug
Package: Scripting Engine problem
PHP Version: 7.0.15
Block user comment: N
Private report: N
New Comment:
While I agree that unsetting the $item is a best practice, the docs only really say you'll run
into issues if you happen to do something with the reference variable. Since I'm not doing that
here, one wouldn't expect references to get created when copying the original variable. Maybe
the docs can be updated to say that foreach by reference will not only leave a variable with a
reference to the last key in the array hanging around, but also the original array may contain
references as well unless you unset the variable.
Previous Comments:
------------------------------------------------------------------------
[2017-01-31 08:57:37] requinix@php.net
Note that var_dump on the array will show references.
The first one looks like a bug as the reference was (supposedly) destroyed, however it comes back
with the foo_copy=foo assignment. https://3v4l.org/DgJFP#v700
The second is not because $item is still a reference after the loop and when $mockCopy copies $mock
it gets foo as a copy *of the reference*. https://3v4l.org/nrpE5 Adding unset($item) is the recommended
solution. http://php.net/foreach
------------------------------------------------------------------------
[2017-01-31 03:08:04] icarpenter at leadid dot com
Description:
------------
After a foreach-by-reference, an array may create references to keys if you create a copy of the
original variable (either directly or indirectly via foreach) and then on that new variable, create
a copy of a key to another key. The original key in that variable will then become a reference to
the same key in the original array.
In PHP 5.6 and 7.1, this can be avoided by either having the foreach run in a different scope, or
unsetting the reference variable after the loop. PHP 7.0 exhibits this behavior regardless.
Test script:
---------------
https://3v4l.org/mHX7B (Triggers the bug in PHP 7.0)
https://3v4l.org/VLuhn (Triggers the bug in PHP 5.6, 7.0, and
7.1)
Expected result:
----------------
string(3) "foo"
Actual result:
--------------
string(3) "bar"
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74020&edit=1