工作中遇到一个 BUG,检查到最后发现是对“引用”的不小心使用导致的,结果是一个 array 的最后两个元素变成相同的了。为了突出主要问题,我把程序的简化形式写在下面。有兴趣的童鞋可以想一想为什么会导致那样的结果。
$list = array(1,2,3);
foreach ( $list as &$item ) {
   $a = $item;
}
//unset($item); // 正确的用法,应该是加上这句。
foreach ( $list as $item ) {
   $a = $item;
}
var_dump($list); // 输出的是 { 1, 2, 2 ],有趣吧?
————————————————————————————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)

解决方案 »

  1.   

    呵呵,这个是老问题啊,几年前就有坛友贴出来过。$list = array(1,2,3);
    $item = & $list[2];//第一次foreach就是这个意思,$item引用数组最后一个元素;
    //unset($item); // 正确的用法,应该是加上这句。
    foreach ( $list as $item ) {//第一次$item被赋予1,则$list[2]相应的值也变成了1,以此类推..
            break;
            //$a = $item;
    }//var_dump($list); // 输出的是 { 1, 2, 2 ],有趣吧?
    var_dump($list);//因为前面的break,这回变成[1,2,1]了。
      

  2.   

    foolbird牛啊,一眼就看出问题所在了。
    赞个。。
    决定仔细看一下程序。
      

  3.   

    Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset(). 
    一查发现手册上好大一个红框,
    配合2L解释.
      

  4.   

    <?php
    $list = array(1,2,3);
    foreach ( $list as &$item ) {
    }// 这时$item指向$list[2]
    foreach ( $list as $item ) {
    // 第一次 这时$list[0] = 1。 所以$list[2]=1    $list = array(1,2,1);
    // 第二次 这时$list[1] = 2。 所以$list[2]=2    $list = array(1,2,2);
    // 第三次 这时$list[2] = 2。 所以$list[2]=2    $list = array(1,2,2);
    }
    print_r($list); // 1,2,2
    这么理解。正确吗?
      

  5.   

    再来一个。<?php
    $list = array(1,2,3,4);
    foreach ( $list as &$item ) {
    }// 这时$item指向$list[3]
    foreach ( $list as $item ) {
    // 第一次 这时$list[0] = 1。 所以$list[3]=1    $list = array(1,2,3,1);
    // 第二次 这时$list[1] = 2。 所以$list[3]=2    $list = array(1,2,3,2);
    // 第三次 这时$list[2] = 3。 所以$list[3]=3    $list = array(1,2,3,3);
    // 第三次 这时$list[3] = 3。 所以$list[3]=3    $list = array(1,2,3,3);
    }
    print_r($list); // 1,2,3,3
      

  6.   

    hehe,看来还真是个老问题,手册里都说过的。汗~~其实我也早就知道引用不解除的话会有隐患,只是一开始想当然地以为即使出问题也应该是第一个元素,加之实际代码是分散在两处,就没往“引用”上想。“末两个元素变成相同”这个现象一开始看觉得非常诡异,楼上各位分析得都对,把过程分解下来看清楚,就很简单了。好了,这个帖子再挂一天就结了  :)
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  7.   

    Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().