php中foreach使用引用的陷阱
有时候我们为了在循环过程中改变数组项的值,在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使用引用的陷阱的更多相关文章
- PHP中foreach有关引用的问题
软件开发的过程中,细节处理非常重要,说得大一点就是细节决定成败,别人不懂的地方,你懂,别人没注意到的细节,你注意到了,这就是你胜出对方的地方,这样就体现出了你的价值. 下面是几个foreach循环中引 ...
- PHP中的&传值引用的问题,在foreach循环的结果能帮解释下输出的结果原理是什么?
PHP中的&传值引用的问题,在foreach循环的结果能帮解释下输出的结果原理是什么? 代码如下: <?php $arr = array('one','two','three'); fo ...
- JavaScript中forEach的用法相关
首先说下JavaScript的forEach的标准格式. 为数组中的每个元素执行指定操作. array1.forEach(callbackfn[, thisArg]) 参数 定义 array1 必需. ...
- PHP和Java中foreach循环的用法区别
1.foreach语句介绍: ①PHP: foreach 语法结构提供了遍历数组的简单方式.foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息. ...
- php中foreach源码分析(编译原理)
php中foreach源码分析(编译原理) 一.总结 编译原理(lex and yacc)的知识 二.php中foreach源码分析 foreach是PHP中很常用的一个用作数组循环的控制语句.因为它 ...
- C#中的线程之Abort陷阱
.简介 C#中通常使用线程类Thread来进行线程的创建与调度,博主在本文中将分享多年C#开发中遇到的Thread使用陷阱. Thread调度其实官方文档已经说明很详细了.本文只简单说明,不做深入探讨 ...
- Java 8 中的方法引用,轻松减少代码量,提升可读性!
1. 引言 Java8中最受广大开发中喜欢的变化之一是因为引入了 lambda 表达式,因为这些表达式允许我们放弃匿名类,从而大大减少了样板代码,并提高了可读性. 方法引用是lambda表达式的一种特 ...
- 『动善时』JMeter基础 — 40、JMeter中ForEach控制器详解
目录 1.什么是逻辑控制器 2.ForEach控制器介绍 3.ForEach控制器的使用 (1)测试计划内包含的元件 (2)获取学院列表请求内容 (3)JSON提取器内容 (4)ForEach控制器内 ...
- 重新想象 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 ...
随机推荐
- Oracle和MySQL在使用上的区别
1. Oracle是大型数据库而MySQL是中小型数据库,MySQL是开源的而Oracle的价格非常高. 2. Oracle支持大并发,大访问量. 3. 安装所用的空间差别也是很大,MySQL安 ...
- 使用 Mesos 管理虚拟机
摘要 为了满足渲染.基因测序等计算密集型服务的需求,UCloud 推出了“计算工厂”产品,让用户可以快速创建大量的计算资源(虚拟机).该产品的背后,是一套基于 Mesos 的计算资源管理系统.本文简要 ...
- Oracle数据库拼音首字母模糊搜索
1.建立函数 CREATE OR REPLACE FUNCTION F_PINYIN(P_NAME IN VARCHAR2) RETURN VARCHAR2 AS V_COMPARE ); V_RET ...
- SQL连接的方法
1.创建连接字符串 string con = "Data Source=127.0.0.1;Initial Catalog=dingdan;Integrated Security=True& ...
- 第一次c++团队合作项目第三篇随笔
这次终于想出来了上次问题的解决方法,就是用多态的方法,让小兵,建筑和英雄继承于Object类,通过指针能实现信息的传递. 同时我也完善了地图中每个Pane类的信息,包括每个格子的位置信息,state( ...
- ios framework 使用图片资源
framework 的制作工程见:http://www.cocoachina.com/ios/20141126/10322.html: 遇到问题: 由于自己的framework 要使用图片资源,最后找 ...
- lintcode-473-单词的添加与查找
473-单词的添加与查找 设计一个包含下面两个操作的数据结构:addWord(word), search(word) addWord(word)会在数据结构中添加一个单词.而search(word)则 ...
- Java中final修饰符深入研究
一.开篇 本博客来自:http://www.cnblogs.com/yuananyun/ final修饰符是Java中比较简单常用的修饰符,同时也是一个被"误解"较多的修饰符.对很 ...
- HDU 2164 Rock, Paper, or Scissors?
http://acm.hdu.edu.cn/showproblem.php?pid=2164 Problem Description Rock, Paper, Scissors is a two pl ...
- 使用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 ...