
代码:
$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, 请问该怎么做呢?
1 shyling Jul 10, 2016 复制引用的形式。。 |
2 GG668v26Fd55CP5W Jul 10, 2016 via iPhone clone |
3 shiny PRO 因为这个是 Object ,其他类型不受影响 |
4 moult Jul 10, 2016 一般情况下,对象传引用,基本数据类型传值。 如果变量前面有取地址符&的话,那么基本数据类型也是传引用。 ``` <?php $list = array(1,2,3); foreach($list as &$value){ $value = $value*2; } unset($value); var_dump($list); ``` 另外,友情提醒,变量记得 unset 掉,不然会有大彩蛋的。 |
5 moult Jul 10, 2016 抱歉,回复的时候没有看仔细。 $new_value = clone $value; 但要任何操作都不会影响,还是得看这个 Object 实现了,__clone()魔法函数可以控制拷贝深度! |
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 更好。 |
9 szopen Jul 11, 2016 在 PHP 7 foreach 默认是复制,详细变更见: https://wiki.php.net/rfc/php7_foreach |
10 Balthild Jul 11, 2016 这么说的话,假如$var1 是 Object ,那$var2 = $var1;实际上是把这个对象的地址给了 $var2 ,而不是复制了一个对象实例? |
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; } } |