Bug #79264 [Opn->Nab]: Value assigned by reference in foreach is do not overwrite to removed variable
| From: | nikic@php.net | Date: | Wed, 12 Feb 2020 10:33:38 +0000 |
| Subject: | Bug #79264 [Opn->Nab]: Value assigned by reference in foreach is do not overwrite to removed variable | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-225524@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=79264&edit=1
ID: 79264
Updated by: nikic@php.net
Reported by: juanparati at gmail dot com
Summary: Value assigned by reference in foreach is do not
overwrite to removed variable
-Status: Open
+Status: Not a bug
Type: Bug
Package: Scripting Engine problem
Operating System: Linux
PHP Version: 7.3.14
Block user comment: N
Private report: N
New Comment:
You need to unset *after* the loop, not *before* it. Otherwise the (still referenced) variables are
going to be used in the following code (in this case the preceding code, because you have an outer
loop).
Previous Comments:
------------------------------------------------------------------------
[2020-02-12 10:18:39] juanparati at gmail dot com
Description:
------------
It's very well documented that behaviour of variables passed by reference into a foreach can
have unexpected behaviours when the variables were previosly used.
From PHP documentation:
"Warning
Reference of a $value and the last array element remain even after the foreach loop. It is
recommended to destroy it by unset(). Otherwise you will experience the following behavior"
However I found that in some cases even when the variable used as reference is previously removed
using "unset" the issue persist.
I can reproduce this issue from PHP 5.6 TO PHP 7.4 with the same result.
It seems that if variables previously are removed (unset) and used again as reference into the
foreach can have a wrong behaviour.
This issue is probably due the way that PHP keep the internal references.
Test script:
---------------
See the following code
https://3v4l.org/h6d0G
The array subnodes "needle" and "haystack" were automatically appended for the
first element of the array even if the variable used as reference was previously removed (unset).
In the following example the result is the expected one when the variables were not previously used:
https://3v4l.org/4kRmH
Expected result:
----------------
array(2) {
["18427e904f7a227e8c3b80dd2858a70e"]=>
array(2) {
["needle"]=>
array(1) {
[0]=>
array(3) {
["starts_at"]=>
int(11821)
["ends_at"]=>
int(14377)
["length"]=>
int(2556)
}
}
["haystack"]=>
array(1) {
[0]=>
array(4) {
["starts_at"]=>
int(12227)
["ends_at"]=>
int(14783)
["length"]=>
int(2556)
["original"]=>
string(3) "foo"
}
}
}
["dd0c26f35ebf55de25eabea3edbfba32"]=>
array(2) {
["needle"]=>
array(1) {
[0]=>
array(3) {
["starts_at"]=>
int(17255)
["ends_at"]=>
int(32431)
["length"]=>
int(15176)
}
}
["haystack"]=>
array(1) {
[0]=>
array(4) {
["starts_at"]=>
int(17776)
["ends_at"]=>
int(33032)
["length"]=>
int(15256)
["original"]=>
string(3) "foo"
}
}
}
}
Actual result:
--------------
array(2) {
["18427e904f7a227e8c3b80dd2858a70e"]=>
array(2) {
["needle"]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(4) {
["starts_at"]=>
int(17255)
["ends_at"]=>
int(32431)
["length"]=>
int(15176)
["original"]=>
string(3) "foo"
}
}
}
["haystack"]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(4) {
["starts_at"]=>
int(17776)
["ends_at"]=>
int(33032)
["length"]=>
int(15256)
["original"]=>
string(3) "foo"
}
}
}
}
["dd0c26f35ebf55de25eabea3edbfba32"]=>
array(2) {
["needle"]=>
array(1) {
[0]=>
array(3) {
["starts_at"]=>
int(17255)
["ends_at"]=>
int(32431)
["length"]=>
int(15176)
}
}
["haystack"]=>
array(1) {
[0]=>
array(3) {
["starts_at"]=>
int(17776)
["ends_at"]=>
int(33032)
["length"]=>
int(15256)
}
}
}
}
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=79264&edit=1