PHP版本为 5.6.12 代码如下:

 
1
2
3
4
5
6
7
8
9
10
11
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);

输出结果

一开始看到第二个 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); 处理,解除地址应用

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使用引用变量的坑的更多相关文章

  1. PHP关于foreach使用引用变量的坑

    写PHP好多年,但仍然会犯低级错误,今天遇到个 foreach中引用变量时的坑,PHP版本为 5.6.12 代码如下: <?php $arr = ['a', 'b', 'c', 'd', 'e' ...

  2. 如何在JMeter中使用ForEach控制器

    Jmeter中的ForEach Controller遍历变量数组. 在这个JMeter教程中,我们将使用ForEach控制器循环访问JSON数组. 有时我们需要解析响应并提取某些信息.例如,在测试AP ...

  3. 说说PHP中foreach引用的一个坑

    From: http://blog.csdn.net/yipiankongbai/article/details/45307767 先来看看下面这段代码: <?php $arr = array( ...

  4. php中foreach使用引用的陷阱

    有时候我们为了在循环过程中改变数组项的值,在foreach的时候变量入口可以加个&符合, 表示,循环过程中使用数组中原来的值,而不是一个复制的值,如 foreach ($array as &a ...

  5. sed中引用变量

    sed 中引用变量 eval sed 's/string/$REPLACE/g' file awk 中引用变量 awk 在匹配字符串的时候,有时候需要需要引用变量. $pid= eval " ...

  6. awk中引用变量使用单引号''

    举例如下 who命令输出第一列 (1)第一种情况不使用引号 # i=1;who | awk '{print $${i}}' 输出如下: awk: {print $${i}} awk:          ...

  7. WiX 中XML引用变量说明

    WiX 安装工程中的XML 文件所引用变量说明: The WiX project supports the following project reference variables: Variabl ...

  8. dos中定义变量与获取常见的引用变量以及四则运算、备份文件(set用法)

    在dos中使用set定义变量: set  a=8              (注意等号两边没有空格) 引用变量如: echo  %a%        将打印a的值 (%a%是获取变量a的值) dos中 ...

  9. PHP使用引用变量foreach时,切记其他循环不要使用同一个名字的变量

    foreach ($log['data'] as $k => &$value) { if ($value['token'] != 0) { $value['change_num'] = ...

随机推荐

  1. linux系统中运行node进程,无法杀死进程

    events.js:72 throw er; // Unhandled 'error' event ^Error: listen EADDRINUSE at errnoException (net.j ...

  2. float布局打破标准流,神助攻clear清浮动

    布局是什么?根据功能划分小块,再根据设计稿还原,书写静态页面,然后再在块里面填充内容,完善功能,js施加交互效果.div作为一个容器,独占一行,代码书写习惯从上至下属于标准流,而浮动float的css ...

  3. alpine安装telnet等工具

    alpine确实是很精简,但是对于熟悉了centos和ununtu的个人来说,实在是不习惯. 因此,记录关于alpine的一些包安装,以及操作细节(逐渐补充). 1. telnet >>& ...

  4. Leetcode:235. 二叉搜索树的最近公共祖先

    Leetcode:235. 二叉搜索树的最近公共祖先 Leetcode:235. 二叉搜索树的最近公共祖先 Talk is cheap . Show me the code . /** * Defin ...

  5. hive中parquet存储格式数据类型timestamp的问题

    当存储格式为parquet 且 字段类型为 timestamp 且 数据用hive执行sql写入. 这样的字段在使用impala读取时会少8小时.建议存储为sequence格式或者将字段类型设置为st ...

  6. vue移动端下拉刷新、上拉加载

    由于自身的项目比较简单,只有几个H5页面,用来嵌入app中,所有没有引入移动端的UI框架,但是介于能让用户在浏览H5页面时有下拉刷新和上拉加载,有更好的用户体验,自己写组件实现. 1.下拉刷新Drop ...

  7. Notability

    Notability 上课记笔记.听网课→Notability 有录音功能, 在原来笔记中新添加空白行(选中之后下移) Notability常用的功能总结 1.纸张有颜色2.荧光笔会盖住文字3.套索工 ...

  8. python数据类型(第一弹)

    作为一门计算机编程语言,python与其它语言一样,设有若干种数据类型,准确掌握各种数据类型的常用方法是精通python的必要条件,也是熟练使用各数据类型.最大限度发挥它们功能的基本条件. pytho ...

  9. Upx 压缩go编译的程序 frp

    1. frp 程序占用大 .路由器 不够空间 2. UPX 下载地址       https://github.com/upx/upx/releases/ 3.  压缩命令  upx.exe -9 C ...

  10. 剑指offer-面试题52-两个链表的第一个公共节点-链表

    /* 题目: 求两个链表的第一个公共节点. */ /* 思路: 见代码. */ #include<iostream> #include<cstring> #include< ...