浅谈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 相关文章推荐
ubuntu 编译安装php 5.3.3+memcache的方法
Aug 05 PHP
PHP连接SQLSERVER 注意事项(附dll文件下载)
Jun 28 PHP
PHP array_multisort() 函数的深入解析
Jun 20 PHP
PHP JS Ip地址及域名格式检测代码
Sep 27 PHP
php和jquery实现地图区域数据统计展示数据示例
Feb 12 PHP
destoon供应信息title调用出公司名称的方法
Aug 22 PHP
浅谈PHP正则表达式中修饰符/i, /is, /s, /isU
Oct 21 PHP
给WordPress的编辑后台添加提示框的代码实例分享
Dec 25 PHP
php正则提取html图片(img)src地址与任意属性的方法
Feb 08 PHP
Laravel中Facade的加载过程与原理详解
Sep 22 PHP
Laravel如何使用Redis共享Session
Feb 23 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
Mar 26 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
php中__toString()方法用法示例
2016/12/07 PHP
基于jQuery的公告无限循环滚动实现代码
2012/05/11 Javascript
UI Events 用户界面事件
2012/06/27 Javascript
基于NodeJS的前后端分离的思考与实践(二)模版探索
2014/09/26 NodeJs
通过Ajax使用FormData对象无刷新上传文件方法
2016/12/08 Javascript
jquery实现轮播图效果
2017/02/13 Javascript
JS自定义滚动条效果简单实现代码
2020/10/27 Javascript
AngularJS遍历获取数组元素的方法示例
2017/11/11 Javascript
jquery在启动页面时,自动加载数据的实例
2018/01/22 jQuery
全站最详细的Vuex教程
2018/04/13 Javascript
Vue中使用方法、计算属性或观察者的方法实例详解
2018/10/31 Javascript
Vue实现一个无限加载列表功能
2018/11/13 Javascript
JS/HTML5游戏常用算法之追踪算法实例详解
2018/12/12 Javascript
详解Vue This$Store总结
2018/12/17 Javascript
vue路由切换时取消之前的所有请求操作
2020/09/01 Javascript
vuecli项目构建SSR服务端渲染的实现
2020/10/30 Javascript
[05:13]2018DOTA2亚洲邀请赛主赛事第二日战况回顾 LGD、VG双雄携手晋级
2018/04/05 DOTA
web.py在模板中输出美元符号的方法
2014/08/26 Python
深入浅析ImageMagick命令执行漏洞
2016/10/11 Python
详解Golang 与python中的字符串反转
2017/07/21 Python
python数据处理之如何选取csv文件中某几行的数据
2019/09/02 Python
一行Python代码制作动态二维码的实现
2019/09/09 Python
在pycharm中为项目导入anacodna环境的操作方法
2020/02/12 Python
python实现126邮箱发送邮件
2020/05/20 Python
python如何导入依赖包
2020/07/13 Python
python math模块的基本使用教程
2021/01/16 Python
一款纯css3实现的颜色渐变按钮的代码教程
2014/11/12 HTML / CSS
食品销售计划书
2014/04/26 职场文书
博士生求职信
2014/07/06 职场文书
党员个人整改措施
2014/10/24 职场文书
2014年终个人工作总结
2014/11/07 职场文书
2014年社区计生工作总结
2014/11/18 职场文书
酒店辞职书怎么写
2015/02/26 职场文书
幼儿园元旦主持词
2015/07/06 职场文书
MySQL CHAR和VARCHAR该如何选择
2021/05/31 MySQL
Golang中异常处理机制详解
2021/06/08 Golang