php foreach 是传值还是传引用? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
gdtv
V2EX    PHP

php foreach 是传值还是传引用?

  •  
  •   gdtv Jul 10, 2016 3431 views
    This topic created in 3580 days ago, the information mentioned may be changed or developed.

    先感谢此网页给我的指导 http://www.netingcn.com/php-foreach-pass-value-reference.html 现在我得知: 如果数组里面存放的是普通类型的元素就是采用传值的方式,存放对象类型元素采用的方式为传地址。

    代码:

    $raw_arr = array( (object)(array('id' => 1, 'name' => 'name1')), (object)(array('id' => 2, 'name' => 'name2')), ); foreach ($raw_arr as $value) { $new_value = $value; //这里也是引用??? $new_value->name = $new_value->name . '-modify'; } print_r($raw_arr); 

    输出:

    Array ( [0] => stdClass Object ( [id] => 1 [name] => name1-modify ) [1] => stdClass Object ( [id] => 2 [name] => name2-modify ) ) 

    我的问题: 我想在 foreach 循环内将$value 传值给一个新变量$new_value ,我希望对$new_value 的任何操作都不会影响原始数组$raw_arr, 请问该怎么做呢?

    Supplement 1    Jul 24, 2016
    感谢大家回复,最后的采用的方法是:$object = unserialize(serialize($object))
    11 replies    2016-07-12 08:54:48 +08:00
    shyling
        1
    shyling  
       Jul 10, 2016
    复制引用的形式。。
    GG668v26Fd55CP5W
        2
    GG668v26Fd55CP5W  
       Jul 10, 2016 via iPhone   1
    clone
    shiny
        3
    shiny  
    PRO
       Jul 10, 2016
    因为这个是 Object ,其他类型不受影响
    moult
        4
    moult  
       Jul 10, 2016
    一般情况下,对象传引用,基本数据类型传值。
    如果变量前面有取地址符&的话,那么基本数据类型也是传引用。
    ```
    <?php
    $list = array(1,2,3);
    foreach($list as &$value){
    $value = $value*2;
    }
    unset($value);
    var_dump($list);
    ```

    另外,友情提醒,变量记得 unset 掉,不然会有大彩蛋的。
    moult
        5
    moult  
       Jul 10, 2016   2
    抱歉,回复的时候没有看仔细。
    $new_value = clone $value;
    但要任何操作都不会影响,还是得看这个 Object 实现了,__clone()魔法函数可以控制拷贝深度!
    dawniii
        6
    dawniii  
       Jul 11, 2016
    @moult 话说大彩蛋是什么呢?
    moult
        7
    moult  
       Jul 11, 2016
    @dawniii
    在执行 foreach($array as &$item) 之后,如果$item 没有 unset 的话,那么$item 这个变量始终指向$array 的最后一个元素。
    也就是如果下面编码的时候没注意,来了个$item='foo_bar'的话,那么 end($array)==='foo_bar',导致$array 内容离奇得不对!尤其是第一年工作的时候,遇到过好几次。。
    所以 foreach 的时候,如果要修改源数组内容,尽量少用&,最好 foreach($array as $key=>$item)!
    当然,如果 foreach 里面没有 break 场景的话,用 array_walk 更好。
    gdtv
        8
    gdtv  
    OP
       Jul 11, 2016
    @moult 就算不用&,如果$array 的元素的类型是 object ,还是引用
    szopen
        9
    szopen  
       Jul 11, 2016
    在 PHP 7 foreach 默认是复制,详细变更见: https://wiki.php.net/rfc/php7_foreach
    Balthild
        10
    Balthild  
       Jul 11, 2016
    这么说的话,假如$var1 是 Object ,那$var2 = $var1;实际上是把这个对象的地址给了 $var2 ,而不是复制了一个对象实例?
    nec
        11
    nec  
       Jul 12, 2016
    如果要改变原数组的值,并且原数组不为对象数组(即为基本数据类型数组),那么就传引用

    上代码:

    $bk_cart_arr = ['1:1','2:1','3:2'];
    $product_id = 1;
    $count = 1;
    foreach ($bk_cart_arr as &$value) { //传引用
    //拿到数组中的每个字符串,并且使用 strpos ()来获取:的位置)
    $index = strpos($value, ":");
    if (substr($value, 0, $index) == $product_id) {
    $count = ((int)substr($value, ($index + 1))) + 1;
    $value = $product_id . ':' . $count;
    break;
    }
    }
    About     Help     Advertise     Blog     API     FAQ     Solana     1129 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 42ms UTC 23:05 PVG 07:05 LAX 16:05 JFK 19:05
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86