有时候我们为了在循环过程中改变数组项的值,在foreach的时候变量入口可以加个&符合,

表示,循环过程中使用数组中原来的值,而不是一个复制的值,如

foreach ($array as &$item) {}

  

这样一来,我们在循环中修改$item的值的时候,实际上修改的是$array中对应的值,

而如果不加&符号的话,在循环中修改$item的值不会影响到$array。

例子:

$array = [
'name' => 'Jobs',
'age' => 50,
]; foreach ($array as $key => $value) {
$value = 22;
}
print_r($array); foreach ($array as $key => &$value) {
$value = 22;
}
print_r($array);

  

Array
(
[name] => Jobs
[age] => 50
)
Array
(
[name] => 22
[age] => 22
)

陷阱:两次循环使用同样的临时变量的情况下,如果第一次循环使用的是引用,

那么在第二次循环中即使没有加&符号,临时变量也是引用。

这个引用指向了数组中最后一个元素(循环到了最后一个元素结束)。

例子:

$array = [
'name' => 'php',
'age' => 123,
]; foreach ($array as $key => &$value) {
echo "key=$key, value=$value" . PHP_EOL;
} foreach ($array as $key => $value) {
echo "key=$key, value=$value" . PHP_EOL;
}

  

key=name, value=php
key=age, value=123
key=name, value=php
key=age, value=php

  

上面最后一行的value是"php",并不是我们期望的123,这是因为,在第二个foreach循环中,

每一次循环的时候,都修改了$array中的key为'age'的值,

第一次循环的时候,数组中的age就已经是php(第一个值)了,在后续的循环中会依次改变数组中最后一个值,

到最后一次循环的时候,取得的值是prev($array),也就是php了。

如何避免这个问题?

1、在第二次循环之前,unset($value)

2、第二次foreach的时候使用不同名字的变量,如$item

另:查看一个变量是否是引用可以使用xdebug_debug_zval函数(需要有xdebug扩展)。

xdebug_debug_zval的结果形如:

value: (refcount=2, is_ref=1)=123

php中foreach使用引用的陷阱的更多相关文章

  1. PHP中foreach有关引用的问题

    软件开发的过程中,细节处理非常重要,说得大一点就是细节决定成败,别人不懂的地方,你懂,别人没注意到的细节,你注意到了,这就是你胜出对方的地方,这样就体现出了你的价值. 下面是几个foreach循环中引 ...

  2. PHP中的&传值引用的问题,在foreach循环的结果能帮解释下输出的结果原理是什么?

    PHP中的&传值引用的问题,在foreach循环的结果能帮解释下输出的结果原理是什么? 代码如下: <?php $arr = array('one','two','three'); fo ...

  3. JavaScript中forEach的用法相关

    首先说下JavaScript的forEach的标准格式. 为数组中的每个元素执行指定操作. array1.forEach(callbackfn[, thisArg]) 参数 定义 array1 必需. ...

  4. PHP和Java中foreach循环的用法区别

    1.foreach语句介绍: ①PHP: foreach 语法结构提供了遍历数组的简单方式.foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息. ...

  5. php中foreach源码分析(编译原理)

    php中foreach源码分析(编译原理) 一.总结 编译原理(lex and yacc)的知识 二.php中foreach源码分析 foreach是PHP中很常用的一个用作数组循环的控制语句.因为它 ...

  6. C#中的线程之Abort陷阱

    .简介 C#中通常使用线程类Thread来进行线程的创建与调度,博主在本文中将分享多年C#开发中遇到的Thread使用陷阱. Thread调度其实官方文档已经说明很详细了.本文只简单说明,不做深入探讨 ...

  7. Java 8 中的方法引用,轻松减少代码量,提升可读性!

    1. 引言 Java8中最受广大开发中喜欢的变化之一是因为引入了 lambda 表达式,因为这些表达式允许我们放弃匿名类,从而大大减少了样板代码,并提高了可读性. 方法引用是lambda表达式的一种特 ...

  8. 『动善时』JMeter基础 — 40、JMeter中ForEach控制器详解

    目录 1.什么是逻辑控制器 2.ForEach控制器介绍 3.ForEach控制器的使用 (1)测试计划内包含的元件 (2)获取学院列表请求内容 (3)JSON提取器内容 (4)ForEach控制器内 ...

  9. 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图

    [源码下载] 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Co ...

随机推荐

  1. Oracle和MySQL在使用上的区别

    1.  Oracle是大型数据库而MySQL是中小型数据库,MySQL是开源的而Oracle的价格非常高. 2.  Oracle支持大并发,大访问量. 3.  安装所用的空间差别也是很大,MySQL安 ...

  2. 使用 Mesos 管理虚拟机

    摘要 为了满足渲染.基因测序等计算密集型服务的需求,UCloud 推出了“计算工厂”产品,让用户可以快速创建大量的计算资源(虚拟机).该产品的背后,是一套基于 Mesos 的计算资源管理系统.本文简要 ...

  3. Oracle数据库拼音首字母模糊搜索

    1.建立函数 CREATE OR REPLACE FUNCTION F_PINYIN(P_NAME IN VARCHAR2) RETURN VARCHAR2 AS V_COMPARE ); V_RET ...

  4. SQL连接的方法

    1.创建连接字符串 string con = "Data Source=127.0.0.1;Initial Catalog=dingdan;Integrated Security=True& ...

  5. 第一次c++团队合作项目第三篇随笔

    这次终于想出来了上次问题的解决方法,就是用多态的方法,让小兵,建筑和英雄继承于Object类,通过指针能实现信息的传递. 同时我也完善了地图中每个Pane类的信息,包括每个格子的位置信息,state( ...

  6. ios framework 使用图片资源

    framework 的制作工程见:http://www.cocoachina.com/ios/20141126/10322.html: 遇到问题: 由于自己的framework 要使用图片资源,最后找 ...

  7. lintcode-473-单词的添加与查找

    473-单词的添加与查找 设计一个包含下面两个操作的数据结构:addWord(word), search(word) addWord(word)会在数据结构中添加一个单词.而search(word)则 ...

  8. Java中final修饰符深入研究

    一.开篇 本博客来自:http://www.cnblogs.com/yuananyun/ final修饰符是Java中比较简单常用的修饰符,同时也是一个被"误解"较多的修饰符.对很 ...

  9. HDU 2164 Rock, Paper, or Scissors?

    http://acm.hdu.edu.cn/showproblem.php?pid=2164 Problem Description Rock, Paper, Scissors is a two pl ...

  10. 使用union all 遇到的问题(俩条sql语句行数的和 不等于union all 后的 行数的和 !);遗留问题 怎么找到 相差的呐俩条数据 ?

    create table buyer as SELECT b.id AS bankid FROM v_product_deal_main m, base_member b WHERE b.id = m ...