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 ...
随机推荐
- #Ubuntu 18.04 安装tensorflow-gpu 1.9
参考 https://tensorflow.google.cn/install/install_linux http://nvidia.com/cuda http://developer.nvidia ...
- CSS3在线实战
作者声明:本博客中所写的文章,都是博主自学过程的笔记,参考了很多的学习资料,学习资料和笔记会注明出处,所有的内容都以交流学习为主.有不正确的地方,欢迎批评指正. 本节课视频网站:https://www ...
- centos上搭建git服务--3
前言:当我们想要实现几个小伙伴合作开发同一个项目,或者建立一个资源分享平台的时候,GIT就是一个很好的选择.当然,既然是一个共有平台,那么把这个平台放到个人计算机上明显是不合适的,因此就要在服务器上搭 ...
- PSP Daily——团队项目Alpha发布
视频展示:优酷视频链接.文案如下 PSP Daily软件NABCD分析: 1) N (Need 需求) PSP Daily 解决了用户(软件工程课上学生)记录例行报告.写每周PSP表格和统计的需求.潜 ...
- Linux发行版本应用场景
如果你是一个Linux爱好者,想选择一个桌面系统,并且既不想用盗版,又不想花太多钱购买商业系统软件,那么可以选择Ubuntu桌面系统.如果你需要服务器端的Linux系统,想用一个比较稳定的服务器系统, ...
- Spring 依赖的Jar包简介
Spring 依赖的Jar包简介 Spring的依赖关系 依赖关系分组 JAR文件 说 明 ant ant.jar, ant-junit.jar, ant-launcher.jar Spring采用A ...
- 初学Objective - C语法之代码块(block)
一.block声明 1.无参数,无返回值: void (^sayHi)(); 2.有参数,有返回值: NSInteger (^operateOfValue)(NSInteger num); block ...
- kafka describe 显示结果解释
> bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic Topic:my- ...
- CentOS7 修改yum源为阿里云
1,登陆root帐号 2,cd /etc/yum.repo.d 3,mv CentOS-Base.repo CentOS-Base.repo.bak4,wget http://mirrors.aliy ...
- java和mysql的length()区别及char_length()
一. mysql里面的有length和char_length两个长度函数,区别在于: length: 一个汉字是算三个字符,一个数字或字母算一个字符. char_length: 不管汉字还是数字或者是 ...