<?php
$arr[0] = 'A';        
$tmp = & $arr[0]; //这个引用传值道底对$arr[0]做了什么?我一直以为这条语句只会改变$tmp的值。$foo = $arr; //这里并没有使用 &
$arr[0] = 'C';print_r($foo);结果:
Array
(
    [0] => C
)为什么结果会是C,而不是A呢?
如果注释掉 $tmp = & $arr[0]; 结果就是A了。
如果$arr[0]只是一个普通变量,而不是一个数组元素,在使用引用传值后也不会出现这种情况。
为什么会这样呢?

解决方案 »

  1.   

    你把整个数组赋值给$foo时, 但其中有一个元素$arr[0]的地址是被引用了, 也就是说数组其中有一个键的地址是被改变了方向, 指向另一个地方的。如果你是这样$arr[0] = 'A';        
    $tmp = & $arr[0];
    $foo = $arr;
    $arr[1] = 'C';  //看这里,  这个元素没有没引用, 下面打印出来的会是A
    print_r($foo);
    这个问题以前也没遇到过, 还多亏楼主有此一问
      

  2.   

    你是指经过$tmp = & $arr[0]; 这条语句之后,$arr[0]中存储的值为一个引用地址?而在这之前,$arr[0]中的值为'A'。这样理解对吗?可为什么普通变量没有这种情况呢,PHP官方是否有相关的文档说明?
      

  3.   

    http://ca2.php.net/manual/en/language.references.whatdo.php#language.references.whatdo.assign看这个页面里的两个NOTE:
    Note: $a and $b are completely equal here. $a is not pointing to $b or vice versa. $a and $b are pointing to the same place. 
    Note: If arrays with references are copied, their values are not dereferenced. This is valid also for arrays passed by value to functions. 正好就是解释你的例子.不过谢谢楼主,没你这个例子,先看时还真没明白:)
      

  4.   

    许久没开发php了,很多都不记得了,如果下面解释错了的话就当笑话看看吧。在php中数组这种数据结构的赋值应该是使用指针,如果要复制一个数组的话需要进行内存的块操作,在java中需要进行ArrayCopy之类的操作。<?php
    $arr[0] = 'A';//这里定义了一个变量,变量指向数组的第一个元素地址,这个数组只有一个元素就是'A'
    $tmp = & $arr[0]; //这里将数组的第一个元素的地址赋值给$tmp$foo = $arr; //这里虽然没有使用&但是将数组赋值给另一个变量时是将数组的第一个元素的地址赋值给变量。这个时候$tmp和$foo以及$arr都指向数组的首地址。
    $arr[0] = 'C';print_r($foo);
    ?>
    修改了第一个元素值后,print $foo or $tmp or $arr得到的结果都是
    Array 

        [0] => C 
      

  5.   

    对引用有了进一步的了解,呵呵。原来一直以为$a=&$b后,对$b没有影响的,原来不是的,$b也受到影响了,$a and $b are completely equal here. $a is not pointing to $b or vice versa. $a and $b are pointing to the same place。$a和$b是完全相同的,并非是$a指向$b或$b指向$a,而是$a和$b指向了同一位置。而数组中的引用还有一个特点:If arrays with references are copied, their values are not dereferenced. This is valid also for arrays passed by value to functions.如果一个带有引用元素的数组(如同LZ的例子,并参看上面的一条)赋值给其他数组变量,赋过去的是引用本身而不是值。函数的数组参数的传递也是如此。以上加上了本人的理解,并非直接翻译哈。
      

  6.   

    If arrays with references are copied, their values are not dereferenced. 
    这句该怎么理解呢?进一步测试:$arr = array('A','B'); //此时$arr[0]存储的是值“A”
    $tmp = & $arr[0]; //此时$arr[0]中的值已变成一个指向“A”的数据空间的地址。$foo = $arr; //赋值后,此时$arr[0]和$foo[0]其实指向同一数据空间。
    $arr[0] = 'change in $arr'; //因此,不管是改变$arr[0],
    $foo[0] = 'change in $foo'; //还是改变$foo[0],都将是对同一数据空间里的值进行操作。echo '($foo)'; print_r($foo);
    echo '($arr)'; print_r($arr);
    以上的注释便是我的理解,不知道对不对?如果正确的话,小弟仍有一事不明白,为啥普通变量不会出现这种情况?例如:$a = "ABC";
    $tmp = & $a; //此时$a中存储的仍然是值“ABC‘,而不会像上面数组元素那样变成值的地址。
      

  7.   


    看看这个应该能理解啦!
    <?php
    function get_arr($arr){
    unset($arr[0]);
    }
    $arr1 = array(1, 2);
    $arr2 = array(1, 2);
    get_arr(&$arr1);
    get_arr($arr2);
    echo count($arr1);
    echo count($arr2);
    print_r($arr1);
    ?>
    <?php
    $test = 'aaaaaa';
    $abc = & $test;
    unset($test);
    echo $abc;
    echo $test;
    ?>
      

  8.   

    这个例子蛮有趣。有一篇文章得先过一过
    http://www.laruence.com/2008/09/19/520.html
    猜想数组的情况亦类似.
    $arr[0] = 'A';        
    $tmp = & $arr[0]; //$arr[0]是个Zval体,is_ref设为1,$foo = $arr;  //数组每个元素共用一个Zval
    $arr[0] = 'C';//因为对应zval的is_ref为1,所以并未发生变量分离。print_r($foo);