您现在的位置是: 首页> 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)

初柒先生 2019-09-18 21:57 php】 【foreach】 【数组 209人已围观

站点信息

  • 建站时间:2019-09-04
  • 网站名称:初柒先生
  • 主题模板《今夕何夕》
  • 文章统计:299条
  • 文章评论:490条
  • 统计数据百度统计
  • 微信公众号:初柒先生(chuqi_sir)
  • 微信扫二维码,关注我们吧!
搜索历史:
0.082411s