PHP 循环引用的问题
问题
为了引出问题, 先来看下面一段代码:
<?php
$arr = [
'a', 'b',
'c', 'd',
]; foreach ($arr as &$each){
echo $each;
}
echo PHP_EOL;
foreach ($arr as $each){
echo $each;
}
这段代码很简单, 输出数组的元素两次, 感觉会输出两次 abcd? 不好意思, 输出结果如下:
是不是感觉很奇怪?我没有给数组赋值啊,数组的最后一个元素怎么在第二次循环的时候改变了呢?
问题分析
再来看下面一段修改过得代码:
<?php
$arr = [
'a', 'b',
'c', 'd',
]; foreach ($arr as &$each){
echo $each;
}
echo PHP_EOL;
$each = '1';
var_dump($arr);
是不是发现了什么?
修改each变量会修改arr的最后一个元素, 这是为什么呢?
有过C语言使用经验的大概一看就明白是怎么回事了.
仔细看上面的foreach循环, each变量使用了&符号, 这个符号相当与c中的取址
php的foreach会在每次循环时,讲当前元素赋值给each, 然后进入循环体
当foreach遍历完成后, each变量没有释放而是指向了arr数组中的最后一个元素, 所以在后面给each赋值时, 其实改变的时arr数组的最后一个元素
到此, 流程已经明白了, 下面还原一下最开始的两次foreach过程:
在第一个foreach完成之后, 显然, each是指向数组的最后一个元素的, 下面进入第二个foreach:
第一次遍历, 将arr[0]赋值给each, 相当于arr[3]=arr[0], 此时arr为: ['a', 'b', 'c', 'a']
第二次遍历, 将arr[1]赋值给each, 相当于arr[3]=arr[1], 此时arr为: ['a', 'b', 'c', 'b']
第三次遍历, 将arr[2]赋值给each, 相当于arr[3]=arr[2], 此时arr为: ['a', 'b', 'c', 'c']
第四次遍历, 将arr[3]赋值给each, 相当于arr[3]=arr[3], 此时arr为: ['a', 'b', 'c', 'c']
分析的结果与之前输出的结果相同, 我们将第二次foreach的每次变化打印出来, 代码如下:
<?php
$arr = [
'a', 'b',
'c', 'd',
]; foreach ($arr as &$each){
}
foreach ($arr as $each){
var_dump($arr);
}
结果截图如下:
结果与我们分析的完全一致, 至此, 完结
我使用的php版本为: 7.2
PHP 循环引用的问题的更多相关文章
- block为什么用copy以及如何解决循环引用
在完成项目期间,不可避免的会使用到block,因为block有着比delegate和notification可读性更高,而且看起来代码也会很简洁.于是在目前的项目中大量的使用block. 之前给大家介 ...
- ios 避免循环引用
类似网络请求的情况下会导致循环引用,但是 如果网络请求的对象是局部变量,就必须用self,不能用weakSelf,否则,一旦当前方法所在对象销毁,那weakSelf就为空了(如果目的是这样,那就另当别 ...
- webapi修改tt模板给字段添加JsonIgnore特性解决转换json循环引用问题
0.问题描述 EF生成的model带有导航属性,则json序列化会报循环引用错误,尝试如下 protected void Application_Start() { GlobalConfigurati ...
- 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
学习 EF Code First+MVC 时遇到了在请求JsonResult时出现 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用 的异常,原因 ...
- 关于json序列化循环引用导致出错
以下是错误信息: Caused by: java.lang.IllegalStateException: circular reference error Offending field: meth ...
- iOS之weak和strong、懒加载及循环引用
一.weak和strong 1.理解 刚开始学UI的时候,对于weak和strong的描述看得最多的就是“由ARC引入,weak相当于OC中的assign,但是weak用于修饰对象,但是他们都不会造成 ...
- 第3月第9天 循环引用 block
一.一个对象没有被引用,那么在函数块完成时就会被dealloc,这种情况因为对象销毁了,block块也永远不会执行. MyNetworkOperation *op = [[MyNetworkOpera ...
- spring jpa 实体互相引用返回restful数据循环引用报错的问题
spring jpa 实体互相引用返回restful数据循环引用报错的问题 Java实体里两个对象有关联关系,互相引用,比如,在一对多的关联关系里 Problem对象,引用了标签列表ProblemLa ...
- 【转】iOS学习之容易造成循环引用的三种场景
ARC已经出来很久了,自动释放内存的确很方便,但是并非绝对安全绝对不会产生内存泄露.导致iOS对象无法按预期释放的一个无形杀手是——循环引用.循环引用可以简单理解为A引用了B,而B又引用了A,双方都同 ...
- iOS 循环引用
1.循环引用一般是指:A持有B,B同时持有A,从而导致死循环无法释放对象. 2.一般循环引用出现在block和delegate中,而一般解决方法就是将self变成weakSelf(强引用变成弱引用), ...
随机推荐
- 如何将RAC数据库的 RMAN Disk 备份 Restore 到另一个节点上的单个实例 (Doc ID 415579.1)
HowTo Restore RMAN Disk backups of RAC Database to Single Instance On Another Node (Doc ID 415579.1) ...
- pip 查看软件包 可用版本并安装; pip 查看 numpy 可用版本并安装
最近需要安装 numpy 的旧版本,发现不知道如何查看可以安装旧版本,解决方法在此进行记录: 然后找到你对应的版本进行安装就可以了: 保持更新,更多精彩内容,请关注 cnblogs.com/xuyao ...
- linux 的swap、swappiness及kswapd原理【转】
本文讨论的 swap基于Linux4.4内核代码 .Linux内存管理是一套非常复杂的系统,而swap只是其中一个很小的处理逻辑. 希望本文能让读者了解Linux对swap的使用大概是什么样子.阅读完 ...
- go语言设计模式之abstract factory
这个代码太多了,调了一晚上. 只能立图证明我测试通过了哈. 真的是工厂的工厂,有点深.
- Mybatis----传入参数parameterType类型详解
Mybatis----传入参数parameterType类型详解 前言 Mybatis的Mapper文件中的select.insert.update.delete元素中有一个parameterType ...
- windows golang安装golang.org/x/net text grpc
使用git # 吧$GOPATH替换成自己的GOPATH git clone https://github.com/golang/net.git $GOPATH\src\golang.org\x\ne ...
- jQuery 源码分析(十四) 数据操作模块 类样式操作 详解
jQuery的属性操作模块总共有4个部分,本篇说一下第3个部分:类样式操作部分,用于修改DOM元素的class特性的,对于类样式操作来说,jQuery并没有定义静态方法,而只定义了实例方法,如下: a ...
- nginx-配置文件样例
1, 总配置文件 user nobody nobody; worker_processes ; worker_rlimit_nofile ; error_log /etc/nginx-idfa/log ...
- 依赖注入在 dotnet core 中实现与使用:3 使用 Lazy<T> 延迟实例化
有些对象我们并不想一开始就实例化,由于性能或者功能的考虑,希望等到使用的时候再实例化.考虑存在一个类 A, 它使用了依赖的类 B,在 A 中,只有某些不常用到的方法会涉及调用 B 中的方法,多数情况下 ...
- -ffast-math编译选项作用
https://stackoverflow.com/questions/7420665/what-does-gccs-ffast-math-actually-do