扫码关注官方订阅号
<?php $arr = array('1','2'); foreach($arr as &$value){ } foreach($arr as $value){ var_dump($value); }
输出
string(1) "1" string(1) "1"
谁给解释一下?
这样解释吧,把foreach展开成赋值的话
foreach
foreach($arr as &$value) { //noop }
大致是
php#begin first foreach $value = &$arr[0]; //noop $value = &$arr[1]; //noop #end foreach
php
#begin first foreach $value = &$arr[0]; //noop $value = &$arr[1]; //noop #end foreach
这时候如果打印$arr,你会看到
array(2) { [0]=> string(1) "1" [1]=> &string(1) "2" }
也就是说$value仍然是$arr[1]的引用(别名)
$value
$arr[1]
然后我们再把第二个foreach拆开
php#begin second foreach $value = $arr[0];//note: 由于$value <=> &$arr[1], 此时$arr[1]被赋值成为$arr[0],也就是1 var_dump($value);//1 $value = $arr[1];//相当于$arr[1] = $arr[1]; 没有实际效果 var_dump($value);//1 #end foreach
#begin second foreach $value = $arr[0];//note: 由于$value <=> &$arr[1], 此时$arr[1]被赋值成为$arr[0],也就是1 var_dump($value);//1 $value = $arr[1];//相当于$arr[1] = $arr[1]; 没有实际效果 var_dump($value);//1 #end foreach
解决方案是永远不要用&
或者老老实实按照官网的指示,用unset解除引用
<?php $arr = array(1, 2, 3, 4); foreach ($arr as &$value) { $value = $value * 2; } // $arr is now array(2, 4, 6, 8) unset($value); // break the reference with the last element ?>
$value 和 $arr[1] 指向同一个内存空间了,第二个循环每次循环实际上改的都是$arr[1]的值
学习了,根据上面的答案简单点来说。 第一个foreach结束后,$value = &$arr[1],注意,这里是引用,可以理解为指针 重点在第二个foreach: 第一次是&$arr[1] = $arr[0],这个是赋值操作,这个时候$arr[1]的值已经已经被修改为$arr[0]了,也就是1.此时$arr = ['0'=>1,'1'=>1]. 第二次&$arr[1] = $arr[1],同上.最终$arr = ['0'=>1,'1'=>1].
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
扫描下载App
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
这样解释吧,把
foreach
展开成赋值的话大致是
这时候如果打印$arr,你会看到
也就是说
$value
仍然是$arr[1]
的引用(别名)然后我们再把第二个foreach拆开
解决方案是永远不要用&
或者老老实实按照官网的指示,用unset解除引用
$value 和 $arr[1] 指向同一个内存空间了,第二个循环每次循环实际上改的都是$arr[1]的值
学习了,根据上面的答案简单点来说。
第一个foreach结束后,$value = &$arr[1],注意,这里是引用,可以理解为指针
重点在第二个foreach:
第一次是&$arr[1] = $arr[0],这个是赋值操作,这个时候$arr[1]的值已经已经被修改为$arr[0]了,也就是1.此时$arr = ['0'=>1,'1'=>1].
第二次&$arr[1] = $arr[1],同上.最终$arr = ['0'=>1,'1'=>1].