先看下面代码

$arr1 = [1, 2];

foreach($arr1 as $key => $value) {
  $value = $value + 1;
} var_dump($key, $value); //结果输出1,3

说明:在上面的foreach循环中,当循环结束后,临时变量 $key和$value变量都不会被自动释放掉。值会被保存下来。而且此时修改$val的值不会影响$arr。

理解foreach的原理,对上面的结果不难理解,foreach循环时,每次循环就会把`$arr1`元素的值复制给临时变量:$key, $value。如,第一次循环时,如下

$key = 0;
$value = $arr1[0];

第二次循环时,如下

$key = 1;
$value = $arr1[1];

再看forach中使用引用

引用:如果想在遍历数组的过程中修改数组的元素,可以在foreach中对$val使用引用。此时被引用的元素$val指向当前数组元素的内存地址,即共享一段内存地址。因此修改$val的值会同时改变$arr[$key]的值。

$arr1 = [1, 2];
foreach($arr1 as $key => $value) {
$value = $value + 1;
}
var_dump($key, $value); //结果输出1,3 var_dump($arr1);
$arr1 的值 为 ['0' => 2, '1' => 3]

说明:$key , $value 的值和上面的非引用情况下一样。在foreach中使用&引用后,当foreach结束后,$key和$val变量也都不会被自动释放掉,但是此时$val和$arrcount($arr) - 1指向相同的内存地址。因此,此时修改$val的值也会改变了$arr[3]的值。

foreach 引用时,原理和上面一样,只不过是引用复制,原来如下

第一次循环:
$key = 0;
$value = &$arr1[0]; 第二次循环:
$key = 1;
$value = &$arr1[1];

再看个例子:

$arr1 = [1, 2];
foreach($arr1 as $key => &$value) {
$value = $value + 1;
}
var_dump($arr1); $value = 100; var_dump($arr1);

第二次输出 $arr1时,第二个元素的值也是100了。

理解了原理,就知道坑了。如果我们2个foreach循环,使用相同的临时变量就会有问题了,一个foreach在使用引用的时候。

如:

$arr1 = [1, 2];
foreach($arr1 as $key => &$value) {
$value = $value + 1;
}
//此时 $value = &$arr1[1] ,后面改变$value的值就会改变$arr1[1]元素的值。
$arr2 = [10, 20, 30];
foreach ($arr2 as $value) {
var_dump($arr1);
}

我们发现在循环$arr2时,$arr2元素复制给$value后,同时$arr1的最后一个元素的值也发生变化,此时等于$arr2此时指针对应元素的值。依次推,$arr1最后一个元素的值 = $arr2元素的最后一个值。

解决方法,使用unset()释放元素, 或者循环第2个数组的时候,使用不同的临时变量

$arr1 = [1, 2];
foreach($arr1 as $key => &$value) {
$value = $value + 1;
}
unset($value);
$arr2 = [10, 20, 30];
foreach ($arr2 as $value) {
var_dump($arr1);
}

最新文章

  1. GJM :Unity使用EasyAR实现脱卡功能
  2. git与github安装、配置、pull、push
  3. Angular2 依赖注入
  4. disconf搭建
  5. DNS(一)之禁用权威域名服务器递归解析
  6. 【08_238】Product of Array Except Self
  7. wince下的CPU和内存占用率计算
  8. CAS单点登录配置[3]:服务器端配置
  9. quick-cocos2d-x android返回键监听并实现原生退出对话框
  10. <原>ASP.NET 学习笔记之HTML helper中参数何时会是路由参数,何时又会是query string?
  11. JavaWEB HTTP请求中POST与GET的区别
  12. Oracle 锁模式
  13. java 自定义的注解有什么作用
  14. 谈下WebSocket介绍,与Socket的区别
  15. djjango安装及其 操作命令
  16. USB包格式解析(转)
  17. mysql 8126
  18. Android Studio 显示 logcat
  19. [js] Array.slice和类数组转数组
  20. 02-05:springboot文件的上传

热门文章

  1. SP19997 MOON2 - Moon Safari (Hard) 【数论,多项式】
  2. (4.1)打造简单OS-小实验[图形显示]
  3. Hyperspectral Images Classification Based on Dense Convolutional Networks with Spectral-Wise Attention Mechanism
  4. Codeforces Round #595 (Div. 3)
  5. 后退欧拉法求解常微分方程(c++)
  6. 【大数据作业十】分布式文件系统HDFS 练习
  7. @Conditional 和 @ConditionalOnProperty
  8. Python语言编写BP神经网络
  9. vue 创建监听,和销毁监听(addEventListener, removeEventListener)
  10. python2中的unicode()函数在python3中会报错: