您现在的位置是: 首页> PHP>php语言在foreach循环使用引用符”&“需要注意的问题 所属分类:PHP
php语言在foreach循环使用引用符”&“需要注意的问题
初柒先生
2019-09-18 21:57
【php】
【foreach】
【数组】
209人已围观
简介在说明PHP语言foreach循环使用引用符”&“需要注意的问题前,我们先了解PHP”写时复制“机制。
在说明PHP语言foreach循环使用引用符”&“需要注意的问题前,我们先了解PHP”写时复制“机制。
1、写时复制
PHP有一个机制叫做”写时复制(Copy on Write,缩写为COW)“,这个机制的作用是减少内存开销、优化程序运行速度。
通过一个例子来说明,先看下面简单的示例代码:
<?php
$a = 1;
$b = $a;
echo $a + $b;
?>
执行上面这段代码,结果输出时2。按照程序运行流程,我们分析这段代码运行流程:
(1)首先给变量a分配一快内存空间,用于存放变量值1;
(2)接着再分配一块内存给变量b,也存放变量值1;
(3)最后通过计算获得结果并输出。
事实上,我们可以发现变量a和变量b存放的变量值都是1,那么两个变量完全可以使用同一块内存。这样的话,内存的使用就可以节省了一块内空间,并且还能省去分配内存和管理内存地址的计算开销。PHP写时复制机制就是这样子,通过这种相同值共享内存的策略,以便达到内存的优化效果。
2、foreach循环使用引用符”&“需要注意的问题
写时复制能给我们带来内存的优化,同时也出现了下面这个问题。
在使用foreach循环时,需要对数据做修改,都会复制数据。如果数据很大,那么就会带来一定的内存消耗。所以为了避免这种复制操作,我们可以使用引用符”&“。
下面这个就是使用引用符”&“出现的问题。
示例1代码:
$arr = array(4, 5, 6);
foreach ($arr as $v) {
//do something here
}
var_dump($arr);
echo '<br>';
foreach ($arr as &$v) {
//do something here
}
var_dump($arr);
echo '<br>';
示例1结果:
array(3) { [0]=> int(4) [1]=> int(5) [2]=> int(6) }
array(3) { [0]=> int(4) [1]=> int(5) [2]=> &int(6) }
示例2代码:
$arr = array(4, 5, 6);
var_dump($arr);
echo '<br>';
foreach ($arr as &$v) {
//do something here
}
foreach ($arr as $v) {
//do something here
}
var_dump($arr);
echo '<br>';
示例2结果:
array(3) { [0]=> int(4) [1]=> int(5) [2]=> int(6) }
array(3) { [0]=> int(4) [1]=> int(5) [2]=> &int(5) }
示例1两次数组打印执行结果问题不大,而示例2两次数组打印执行结果最后一位数据出现了问题。
我们分析一下示例2代码:
(1)执行第一个带引用的foreach循环
一开始, $v指向$arr[0]的存储空间,空间内存储着 4 。 foreach执行结束时,$v指向$arr[2]的存储空间,空间内存储着 6 。
(2)执行第二个没有引用foreach循环
执行第二个没有引用foreach循环,使用的是赋值方式,即数组$arr的值依次赋值给变量$v。在进行第一个元素赋值时,即把$ar[0]赋值给变量$v ,而问题就出现在这里。由于刚执行完第一个foreach循环, $v不是一个新变量,而是已经存在的且指向$arr[2]的那个引用。如此一来,再对$v进行赋值时,就将$arr[0] = 4写入$arr[2]的实际存储空间,相当于对 $arr[2] 进行赋值。依此类推,第二个foreach循环执行的结果, 就是数组的最后一个元素变成了倒数第二个元素的值。
3、解决方法
(1)不使带引用的foreach循环, 改用如下代码,这种方式会损失一下效率,但是可以保证输出结果正确。
foreach ($arr as $k => $v) {
//使用$arr[$k]赋值修改原始数组
}
(2)在带引用的foreach循环结束后,重置变量$v(最终效率跟原来的没太大差别)
unset($v);
很赞哦! (0)
相关文章
文章评论
猜你喜欢
