Bug #53863 [Opn->Nab]: scalar reference of array element has unintended side effects

From: 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

« previous php.bugs (#188664) next »