|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2011-01-28 07:45 UTC] 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
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Oct 28 08:00:01 2025 UTC |
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); ?>