php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #53863 scalar reference of array element has unintended side effects
Submitted: 2011-01-28 07:45 UTC Modified: 2014-11-18 21:15 UTC
Votes:4
Avg. Score:3.8 ± 0.4
Reproduced:4 of 4 (100.0%)
Same Version:1 (25.0%)
Same OS:2 (50.0%)
From: elrah at polyptych dot com Assigned:
Status: Not a bug Package: Variables related
PHP Version: 5.3.5 OS: CentOS 5.5
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: elrah at polyptych dot com
New email:
PHP Version: OS:

 

 [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


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-11-18 20:07 UTC] 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); 

?>
 [2014-11-18 21:15 UTC] rasmus@php.net
-Status: Open +Status: Not a bug
 [2014-11-18 21:15 UTC] 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-19 15:32 UTC] sohagan at gmail dot com
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")
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 13:01:31 2024 UTC