PHP关于foreach使用引用变量的坑
2016-07-29 11:42
519 查看
写PHP好多年,但仍然会犯低级错误,今天遇到个 foreach中引用变量时的坑,PHP版本为 5.6.12 代码如下:
输出结果:
一开始看到第二个 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]
解决办法:
尽量不使用相同的循环变量名;
每次使用完或再次使用前进行 unset($a); 处理,解除地址应用
还是用上面代码示例:
输出结果:
现在就正常了,这些小细节一定要注意了
<?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);
输出结果:
一开始看到第二个 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]
解决办法:
尽量不使用相同的循环变量名;
每次使用完或再次使用前进行 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);
输出结果:
现在就正常了,这些小细节一定要注意了
相关文章推荐
- yii2读写分离配置
- HighCharts/Highstock使用小结,使用汉化及中文帮助文档
- jq 使用php输出一问 一答的列表 点击某个相应问题展开相应回答
- zend opcache的最佳设置
- php7 新特性
- PHP邮件发送类(修改网上代码,亲测可用)
- 【php】连接mysql的几种方法
- PHP注释的艺术——phpDoc规范
- PHP详解$_SEVER常用变量
- Yii 1.1操作Cookie
- PHP7新特性的介绍
- Yii createCommand CURD操作
- PHP删除目录及目录下所以文件
- PHP smarty函数
- phpstorm 解决svn 无法提交的问题
- 封装php的非对称加密RSA
- PHP中使用CURL实现GET和POST请求
- yii2框架-restful的自定义api(二十二)
- 在Thinkphp3.2 中使用PHPMailer 发送邮件
- ThinkPHP接入支付宝支付功能