浅谈PHP中关于foreach使用引用变量的坑


Posted in PHP onNovember 14, 2016

写PHP好多年,但仍然会犯低级错误,今天遇到个 foreach中引用变量时的坑,PHP版本为 5.6.12 代码如下:

<?php
$arr = ['a', 'b', 'c', 'd', 'e'];
foreach ($arr as $i=>&$a) {
  $a = $a.'_'. $a;
  echo $a .'<br>';
}
echo '<hr>';
foreach ($arr as $i=>$a) {
  echo $a .'<br>';
}
echo '<hr>';
print_r($arr);

输出结果

浅谈PHP中关于foreach使用引用变量的坑

一开始看到第二个 foreach 输出的结果感觉很是莫名其妙,怎么会输出两个 d_d 呢?

仔细想了想,原来因为PHP foreach 中的 $a 的作用域是整个函数的局部变量,在循环外部仍然有效,而不是被封闭在循环内的,

所以当执行第二个foreach 时的 $a 并不是新的变量,而是仍然指向 $arr 数组第5个元素的地址引用,

当第二个 foreach 在循环时实际上是在不停的给 $arr 数组的第5个元素赋值,

具体赋值情况,

第一次:a_a 赋值给第5个元素, 结果为: [a_a, b_b, c_c, d_d,a_a]

第二次:b_b 赋值给第5个元素,结果为: [a_a, b_b, c_c, d_d,b_b]

第三次:c_c 赋值给第5个元素,结果为: [a_a, b_b, c_c, d_d,c_c]

第四次:d_d 赋值给第5个元素,结果为: [a_a, b_b, c_c, d_d,d_d]

第五次:此时因为第五个元素已经变成 d_d 又重新把 d_d 赋值给第5个元素,结果还是为: [a_a, b_b, c_c, d_d,d_d]

解决办法:

1.尽量不使用相同的循环变量名;

2.每次使用完或再次使用前进行 unset($a); 处理,解除地址应用

还是用上面代码示例:

$arr = ['a', 'b', 'c', 'd', 'e'];
foreach ($arr as $i=>&$a) {
  $a = $a.'_'. $a;
  echo $a .'<br>';
}
echo '<hr>';
echo $a;
echo '<hr>';

// 这里 unset 掉
unset($a);

echo $a = 'ccc';
echo '<hr>';
print_r($arr);
echo '<hr>';
foreach ($arr as $i=>$a) {
  echo $a .'<br>';
}
echo '<hr>';
print_r($arr);

输出结果:

浅谈PHP中关于foreach使用引用变量的坑

现在就正常了,这些小细节一定要注意了

以上就是小编为大家带来的浅谈PHP中关于foreach使用引用变量的坑全部内容了,希望大家多多支持三水点靠木~

PHP 相关文章推荐
杏林同学录(三)
Oct 09 PHP
简单示例AJAX结合PHP代码实现登录效果代码
Jul 25 PHP
fgetcvs在linux的问题
Jan 15 PHP
Notice: Trying to get property of non-object problem(PHP)解决办法
Mar 11 PHP
Thinkphp的volist标签嵌套循环使用教程
Jul 08 PHP
CodeIgniter针对lighttpd服务器URL重写的方法
Jun 10 PHP
CI框架整合smarty步骤详解
May 19 PHP
PHP实现网页内容html标签补全和过滤的方法小结【2种方法】
Apr 27 PHP
关于php支持的协议与封装协议总结(推荐)
Nov 17 PHP
详解PHP变量传值赋值和引用赋值变量销毁
Mar 23 PHP
PHP设计模式之抽象工厂模式实例分析
Mar 25 PHP
php中的钩子理解及应用实例分析
Aug 30 PHP
利用switch语句进行多选一判断的实例代码
Nov 14 #PHP
PHP表单验证内容是否为空的实现代码
Nov 14 #PHP
PHP环境搭建(php+Apache+mysql)
Nov 14 #PHP
10个值得深思的PHP面试题
Nov 14 #PHP
PHP生成word文档的三种实现方式
Nov 14 #PHP
php版微信返回用户text输入的方法
Nov 14 #PHP
THinkPHP获取客户端IP与IP地址查询的方法
Nov 14 #PHP
You might like
PHP4实际应用经验篇(1)
2006/10/09 PHP
php动态生成JavaScript代码
2009/03/09 PHP
php编写的简单页面跳转功能实现代码
2013/11/27 PHP
curl实现站外采集的方法和技巧
2014/01/31 PHP
PHP提示Deprecated: mysql_connect(): The mysql extension is deprecated的解决方法
2014/08/28 PHP
详解WordPress开发中用于获取分类及子页面的函数用法
2016/01/08 PHP
Zend Framework入门教程之Zend_Config组件用法详解
2016/12/09 PHP
纯js实现的论坛常用的运行代码的效果
2008/07/15 Javascript
Html中JS脚本执行顺序简单举例说明
2010/06/19 Javascript
JavaScript中的排序算法代码
2011/02/22 Javascript
详解AngularJS的通信机制
2015/06/18 Javascript
纯html+css+javascript实现楼层跳跃式的页面布局(实例代码)
2017/10/25 Javascript
layui表格数据复选框回显设置方法
2019/09/13 Javascript
Vue props中Object和Array设置默认值操作
2020/07/30 Javascript
JS+Canvas实现五子棋游戏
2020/08/26 Javascript
[43:35]TI4 循环赛第二日Liquid vs Fnatic
2014/07/11 DOTA
Python 实现简单的shell sed替换功能(实例讲解)
2017/09/29 Python
详谈python3中用for循环删除列表中元素的坑
2018/04/19 Python
python selenium自动上传有赞单号的操作方法
2018/07/05 Python
Python人脸识别第三方库face_recognition接口说明文档
2019/05/03 Python
Django如何简单快速实现PUT、DELETE方法
2019/07/24 Python
Django Rest framework频率原理与限制
2019/07/26 Python
详解Selenium 元素定位和WebDriver常用方法
2020/12/04 Python
Python 利用flask搭建一个共享服务器的步骤
2020/12/05 Python
欧洲领先的电子和电信零售商和服务提供商:Currys PC World Business
2017/12/05 全球购物
法国包包和行李箱销售网站:Bagage24.fr
2020/03/24 全球购物
描述一下JVM加载class文件的原理机制
2013/12/08 面试题
南京软件公司的.net程序员笔试题
2014/08/31 面试题
请解释流与文件有什么不同
2016/07/29 面试题
初任培训自我鉴定
2013/10/07 职场文书
一年级数学教学反思
2014/02/01 职场文书
班组拓展活动方案
2014/08/14 职场文书
2014大四本科生自我鉴定总结
2014/10/04 职场文书
2015新员工试用期工作总结
2014/12/12 职场文书
经典搞笑版检讨书
2015/02/19 职场文书
企业安全隐患排查治理制度
2015/08/05 职场文书