foreach引用坑
先看下面代码
$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);
}
foreach引用坑的更多相关文章
- 说说PHP中foreach引用的一个坑
From: http://blog.csdn.net/yipiankongbai/article/details/45307767 先来看看下面这段代码: <?php $arr = array( ...
- php foreach引用赋值
在写代码时发现php foreach引用赋值会导致意外的行为. 代码示例: <?php $arr = array('a','b','c'); foreach($arr as $k=>&am ...
- foreach 引用传值&
foreach 引用传值& php 怎么在foreach中循环数组 ,的时候添加元素跟值 foreach($arr as $key => &$vo){ //注意,由于上面遍 ...
- PHP 数组 foreach引用导致的bug
<?php $arr = array('a', 'b', 'c'); foreach($arr as &$v) {} foreach($arr as $v) {} var_dump($a ...
- for-each的坑(Hollis)
直接用代码来说明: public class ForEach { public static void main(String[] args) { List<String> list = ...
- Visual Studio 2015下编译zmq项目下其他项目踩进的项目引用坑
PS.在之前的一篇文章中介绍了如何用Visual Studio 2015编译zmq,在编译同解决方案中除了libzmq之外的项目例如inproc_thr时会报错误,具如下: Severity Code ...
- PHP foreach引用&
将以下代码打印 $variable = ['a', 'b', 'c']; foreach ($variable as $key => &$value) { } foreach ($var ...
- PHP foreach 引用 &
以前用foreach,总喜欢在第二次遍历时改变value的拼写,比如 $x = array("a", "b", "c"); foreach ...
- forEach的坑
使用js里的forEach来遍历数组的时候需要注意的是:break,return语句不能使其中断,它还是会继续遍历完数组的每一个元素 错误代码: function nameExit(name){ da ...
随机推荐
- 关于System.BadImageFormatException
什么是BadImageFormatException BadImageFormatException是当动态链接库 (DLL) 或可执行程序的文件映像无效时引发的异常. 可能的原因 如果动态链接库 ( ...
- pgloader 学习(五)pgloader 参考手册
pgloader将各种来源的数据加载到PostgreSQL中.它可以转换动态读取的数据,并在加载前后提交原始SQL. 它使用COPY PostgreSQL协议将数据流式传输到服务器,并通过填充一对re ...
- 使用chrome浏览器调试移动端网页(非模拟访问)
1. 使用数据线连接手机与电脑 2. 打开手机调试模式 参考:http://jingyan.baidu.com/article/f79b7cb35ada4d9145023e63.html 本人使用的m ...
- 【洛谷P5049】旅行(数据加强版)
题目链接 m=n-1是直接按字典序dfs就行, m=n时是一棵基环树,我们发现当一个点在环上时,可以把它和它的一个在环上的儿子之间的边删掉,然后回溯,到达它的第一个有其他儿子的祖先的另一个儿子上,我们 ...
- 【UVA11987】Almost Union-Find
题目链接 题目就告诉我们要用并查集了,操作1和3用裸的带权并查集就行了, 操作2相当于将p结点从当前树中删除,再插入到q的树中,直接删除的话比较麻烦,不妨把它的"尸体"留在原来的地 ...
- GoCN每日新闻(2019-10-09)
GoCN每日新闻(2019-10-09) GoCN每日新闻(2019-10-09) 1. 我们如何将服务延迟减少了98% https://blog.gojekengineering.com/the-n ...
- Linux进阶之Shell编程
1.什么是Shell Shell是一个命名行解释器,它为用户提供一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动.挂起.停止甚至是编写一些程序. 2.Shell脚本 ...
- Linux系统学习(二)一Linux基本操作
一.Linux的目录结构 1.1 Linux的目录结构图 1.2 目录内容 /:这就是根目录.对你的电脑来说,有且只有一个根目录.所有的东西,我是说所有的东西都是从这里开始.举个例子:当你在终端里输入 ...
- crontab定时任务接入
# 查看 $ crontab -l # 创建 $ crontab -e # 每分钟输出一次当前时间 * * * * * echo `date` >> /demo.log # 查看定时 $ ...
- git,指南,操作
助你开始使用 git 的简易指南,木有高深内容,;). Tweet 作者:罗杰·杜德勒 感谢:@tfnico, @fhd and Namics其他语言 english, deutsch, españo ...