From: http://blog.csdn.net/yipiankongbai/article/details/45307767

先来看看下面这段代码:

<?php
$arr = array('apple','banana','cat','dog');
foreach($arr as $key=>$val)
{
//some code
} echo $val; //输出dog
echo $key; //输出3 //下面对val进行赋值
$val = 'e';
print_r($arr); //输出Array ( [0] => apple [1] => banana [2] => cat [3] => dog )

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

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

再来看看下面一段在foreach中使用引用的代码,这是最近在项目中遇到的一种情况:

<?php
$arr = array('apple','banana','cat','dog');
//在foreach中使用引用
foreach($arr as $key => &$val)
{
$val = 'new value';
} echo $val; //输出new value
echo $key; //输出3 $val = 'egg';
print_r($arr); //输出Array ( [0] => new value [1] => new value [2] => new value [3] => egg )

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

这种情况下很容易犯的错误就是像上面例子所示,在循环外面继续使用被foreach引用的变量,这样会使开发者得不到预期的数据。因此,为了避免这种情况的发生,应该在适当的位置释放变量的引用。以上面的代码为例:

<?php
$arr = array('apple','banana','cat','dog');
//在foreach中使用引用
foreach($arr as $key => &$val)
{
$val = 'new value';
}
unset($val); echo $val; //报错,Notice: Undefined variable: val
echo $key; //输出3 $val = 'egg';
print_r($arr); //输出Array ( [0] => new value [1] => new value [2] => new value [3] => new value ) 在foreach结束后unset $val,此时会释放对$val的引用。因此改变$val不会对$arr造成影响。

这是最近在项目中遇到的坑和解决方案的总结,如果错误或更好地建议,欢迎指出。

原文地址:http://www.aintnot.com/2015/04/25/talk-about-a-hole-in-php-foreach-quote/

最新文章

  1. Linux应用程序基础
  2. Objective-C 排序
  3. Android中ExpandableListView的使用
  4. Razor练习3
  5. 详解Javascript 函数声明和函数表达式的区别
  6. Shooting Algorithm
  7. discuz云平台报调用远程接口失败的问题分析和解决
  8. 洛谷P1294 高手去散步
  9. 如何区分Shapefile,Coverage,Geodatabase(转载)
  10. keepalive学习
  11. 每天一个linux命令(54)--watch命令
  12. 服务器返回webview字符串,用该字符串填满整个屏幕,不可缩放
  13. Ubuntu16.04安装使用wineqq
  14. Scrapy爬虫入门
  15. POJ 2408 - Anagram Groups - [字典树]
  16. jquery ajax 设置请求头header 参数
  17. tensorboard简单使用
  18. 《深入理解计算机系统》学习总结 Chap7
  19. ASP.NET Web Api OwinSelfHost Restful 使用
  20. 极简操作无需root隐藏S8导航栏和状态栏

热门文章

  1. Nginx缓存功能、防盗链、URL重写
  2. 基于jQuery垂直多级导航菜单代码
  3. Bootstrap+Angularjs自制弹框
  4. hbase的写和读,大合并和小合并
  5. TCP/IP协议层
  6. 【整理】fiddler不能监听 localhost和 127.0.0.1的问题
  7. mysql 分区处理数据
  8. PHP和MySQL实现消息队列
  9. 自然语言交流系统 phxnet团队 创新实训 项目博客 (七)
  10. svn解决不能clean的方法