Bug #53863 [Com]: scalar reference of array element has unintended side effects

From: Date: Wed, 19 Nov 2014 15:32:39 +0000
Subject: Bug #53863 [Com]: scalar reference of array element has unintended side effects
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-188683@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 Comment by: sohagan at gmail dot com Reported by: elrah at polyptych dot com Summary: scalar reference of array element has unintended side effects 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: Here's the relevant documention showing that this is expected behaviour: http://php.net/manual/en/language.references.whatdo.php (search for "Assignment of array variables") Previous Comments: ------------------------------------------------------------------------ [2014-11-18 21:15:48] rasmus@php.net 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. ------------------------------------------------------------------------ [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 (#188683) next »