对数组两次foreach的使用陷阱

对数组两次foreach的使用陷阱
对同一个数组两次foreach备注
这个问题是作小论坛的时候遇见的
若是单纯的对一个数组两次foreach是没什么问题的数组

clipboard.png

输出:spa

clipboard.png

若是在第一次foreach的时候,加了引用呢?3d

clipboard.png

输出:指针

clipboard.png

第二次的结果是 a b b,并非数组的值
也就是说这种状况下,foreach循环最后一次的值和数组倒数第二个的值是同样的blog

clipboard.png

输出:ip

clipboard.png

为何第二次结果是a b b呢?
foreach循环时,是经过移动数组内部指针来实现的
第一次foreach循环时,$v为引用变量
于是$v 与 $arr[2] 指向了同一个地址空间(共享变量值)
因此以后对$v的任何修改都会直接影响$arr
图解:内存

clipboard.png

第二次foreach的第一次循环时,$v被赋值为$arr[0],也就是a
而在第一次foreach结束时,$v最终指向了$arr[2],他们指向同一个地址空间
因此第二次foreach的第一次循环时,$v的值成了a,$arr[2]也就变成了a
第二次foreach的第二次循环时,$v的值成了b,$arr[2]也就变成了b
因此,数组$arr的值就成了a b b
因此第三次循环时,$v的值就成了bit

上面说的明白,不过···
第二次foreach循环时,$v=$arr[0],按照以前说的,$v的指向不是指向了$arr[0]吗?
也就是说$v和$arr[0]指向同一内存地址,由于$arr和$v都没有发生值的变化
这里咱们须要先了解一个知识点:class

clipboard.png

结果:
1
2
2变量

clipboard.png

结果:
2
2
2

主要是这代码的运行结果:
我觉得上面的代码中$v和$b应该指向同一zval,而$a的值不会被改变,但事实并不是这样
是否是说一个变量的引用(&)没有消失,对这个变量从新赋值(非引用)其它变量的时候,其内存地址不会发生变化,也就是该变量的引用、指向内存地址的那条线不会改变,只是值变化

clipboard.png

结果:
1
2
2

clipboard.png

结果:
1
2
2

因此,结果才会这样

clipboard.png

输出:

clipboard.png

那如今又有这样一个疑虑,理论上在第二次foreach循环中,不会拷贝数组,这里$arr的值虽然发生了变化,但并非直接经过$arr[$k]这样的方式去改变的,而是$v的值被改变,$v是个临时变量,间接的影响到了$arr数组的值,因此数组不会拷贝
(目前没想到更有说服力的理由)

三种解决方案:① 第二次foreach循环,别用$v了② 第二次foreach循环以前,unset($v)$v的引用在 foreach 循环以后仍会保留。建议使用unset()将其销毁③ 第二次循环也用&

相关文章
相关标签/搜索