Bug #53863 [Opn->Nab]: scalar reference of array element has unintended side effects
| From: | rasmus@php.net | Date: | Tue, 18 Nov 2014 21:15:49 +0000 |
| Subject: | Bug #53863 [Opn->Nab]: scalar reference of array element has unintended side effects | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-188664@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=53863&edit=1
ID: 53863
Updated by: rasmus@php.net
Reported by: elrah at polyptych dot com
Summary: scalar reference of array element has unintended
side effects
-Status: Open
+Status: Not a bug
Type: Bug
Package: Variables related
Operating System: CentOS 5.5
PHP Version: 5.3.5
Block user comment: N
Private report: N
New Comment:
There isn't actually a bug here. This is how references work and there is no change of
behaviour from one version to the next. All versions of PHP give the same result here.
Previous Comments:
------------------------------------------------------------------------
[2014-11-18 20:07:33] sohagan at gmail dot com
In PHP 5.3.3 (on Linux 2.6.32-431.23.3.el6.x86_64), there is a related(identical?) bug which causes
the last element of an array to be passed/assigned by reference if its parent array is used as a
reference.
For example, foreach ($my_array as &$array_val) {...} will cause the last element of $my_array
to be assigned by reference:
$my_new_array = $my_array;
$my_new_array[4] = null; // if $my_array's last index is 4, this will nullify that value
too
and passed by reference:
function dont_touch($param) { // modify $param here }
dont_touch($my_array[4]); // $my_array[4] will be modified
This can be fixed by unsetting the reference to the array value after the foreach loop.
unset($array_val); // after the foreach loop
Try running this code and comment/uncomment the line containing "unset".
<?php
$thingies = array(array(1,2,3,4),array(1,2,3,4));
var_dump($thingies);
foreach ($thingies as &$things) {
foreach ($things as $thing) {
$thing += 1;
}
}
unset($things);
$copythings = $thingies;
$copythings[1][0] += 1;
$copythings[1][1] += 1;
$copythings[1][2] += 1;
$copythings[1][3] += 1;
var_dump($thingies);
?>
------------------------------------------------------------------------
[2011-01-28 07:45:28] elrah at polyptych dot com
Description:
------------
Adding a scalar reference to an array element changes array assignment behavior.
In a regular array assignment, elements are all copied by value. But if a scalar
reference has been made to an array element, that element is copied by reference
in a subsequent array assignment. The code looks exactly the same, so the
behavior shouldn't change just because there's a reference floating out there
somewhere.
Test script:
---------------
<?php
$arr1 = array(1);
echo "\nbefore:\n";
echo "\$arr1[0] == {$arr1[0]}\n";
$arr2 = $arr1;
$arr2[0]++;
echo "\nafter:\n";
echo "\$arr1[0] == {$arr1[0]}\n";
echo "\$arr2[0] == {$arr2[0]}\n";
$arr3 = array(1);
$a =& $arr3[0];
echo "\nbefore:\n";
echo "\$a == $a\n";
echo "\$arr3[0] == {$arr3[0]}\n";
$arr4 = $arr3;
$arr4[0]++;
echo "\nafter:\n";
echo "\$a == $a\n";
echo "\$arr3[0] == {$arr3[0]}\n";
echo "\$arr4[0] == {$arr4[0]}\n";
Expected result:
----------------
before:
$arr1[0] == 1
after:
$arr1[0] == 1
$arr2[0] == 2
before:
$a == 1
$arr3[0] == 1
after:
$a == 1
$arr3[0] == 1
$arr4[0] == 2
Actual result:
--------------
before:
$arr1[0] == 1
after:
$arr1[0] == 1
$arr2[0] == 2
before:
$a == 1
$arr3[0] == 1
after:
$a == 2
$arr3[0] == 2
$arr4[0] == 2
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=53863&edit=1