文档章节

PHP数组foreach时使用&改变值问题

hirainn
 hirainn
发布于 2016/09/08 14:13
字数 551
阅读 107
收藏 1
/*
2016.11.14更新
以下理解有误,关于PHP引用变量与指针是有区别,PHP的变量名与变量内容是不同的东西,引用变量相当于一个新的变量名指向
同一个变量内容
将下面图中的地址比如 0x.... 的地址替换为不同的变量名去理解才是OK的
人懒,不想重新画图。懂意思就好
*/

 

遇到一个问题,对数组进行遍历的时候,如果使用引用变量&V操作值,如果不及时unset掉的话,后续可能会出现问题。

<?php
$arr = [1,2,3,4,5];
foreach($arr as &$v){
    echo "$v ";
}
echo '<br />';
// 第二次是$v 而不是 &$v
foreach($arr as $v){
    echo "$v ";
}
echo '<br />';
print_r($arr);
?>

运行结果如下图:

为什么第二次打印的是 1 2 3 4 4呢?

此处的$v是一个引用变量,每次foreach的时候,其实有两个过程,取值,再赋值。电脑通过内存地址取值,&的过程,就是将变量的内存地址赋值给变量。

                                                          图一

foreach的时候,因为是as &$v,所以会依次将数组中的每个值的地址给$v,如果用foreach($arr as $k => &$v)表示的话,可以理解为,$v = &$arr[$k]。每一次都是取地址,因此不会改变数组的值。当第一次数据遍历结束的时候,$v指向的时候数组arr的最后一个单元。

当第二次遍历的时候,还是按照foreach($arr as $k => $v)来画图,$k是arr的索引,而$v指向arr最后一个值的地址,这里是$arr[4],因为每次的过程大概为下图

第一次将arr[0]取出赋值给$v,同时因为$v指向arr[4]的地址,所以会用arr[0]的值覆盖arr[4]的值,往后同理

最后一次,因为arr[4]已经是4了,所以覆盖自身,仍然是4

因此 最后的结果 是1 2 3 4 4。如果将第二个foreach中的$v也换为&$v,那么就会重新改变$v的指向,这种情况下就重复图一的过程,而不会改变$arr的值

© 著作权归作者所有

hirainn
粉丝 35
博文 84
码字总数 65318
作品 0
深圳
程序员
私信 提问
加载中

评论(2)

hirainn
hirainn 博主
以上过程有误,关于PHP的引用,是PHP的变量名及其值存在于两个不同的空间,将上图下面的地址改为变量名理解
MousseQin
MousseQin
好厉害
PHP关于foreach的问题

手册上的一个warning 大神们来说说这里最后一个元素$n对后面个foreach的影响,怎么改变值的,很不理解啊

名字不能超过十个字
2013/01/15
2.1K
11
smarty中foreach的用法

{foreach},{foreachelse} {foreach} 用于像循环访问一个数字索引数组一样循环访问一个关联数组,与仅能访问数字索引数组的{section}不同,{foreach}的语法比 {section}的语法简单得多,但是作...

_大雁
2013/11/23
66
0
深入理解PHP之数组遍历

本文地址: http://www.laruence.com/2009/08/23/1065.html 经常会有人问我, PHP的数组, 如果用foreach来访问, 遍历的顺序是固定的么? 以什么顺序遍历呢? 比如: $val) { //结果是什么? } 又比...

晨曦之光
2012/03/09
178
1
php数组循环输出实现方法【实例代码有误!!】

以前我们经常会想怎么来实现php数组循环输出来,本文章来介绍了利用php中常用的四种循环语句来实现单数组或多维数组循环输出方法. 在 PHP 中,我们可以使用下列循环语句: while 只要指定的条件...

adbug
2016/04/11
116
0
深入理解PHP之数组(遍历顺序)

经常会有人问我, PHP的数组, 如果用foreach来访问, 遍历的顺序是固定的么? 以什么顺序遍历呢? 比如: <?php $arr['laruence'] = 'huixinchen'; $arr['yahoo'] = 2007; $arr['baidu'] = 2008; ......

botkenni
2016/10/09
28
0

没有更多内容

加载失败,请刷新页面

加载更多

一起来学Java8(四)——复合Lambda

在一起来学Java8(二)——Lambda表达式中我们学习了Lambda表达式的基本用法,现在来了解下复合Lambda。 Lambda表达式的的书写离不开函数式接口,复合Lambda的意思是在使用Lambda表达式实现函...

猿敲月下码
35分钟前
9
0
debian10使用putty配置交换机console口

前言:Linux的推广普及,需要配合解决实际应用方能有成效! 最近强迫自己用linux进行实际工作,过程很痛苦,还好通过网络一一解决,感谢各位无私网友博客的帮助! 系统:debian10 桌面:xfc...

W_Lu
今天
10
0
aelf Enterprise 0.8.0 beta有奖公测,“Bug奖金计划”重磅开启

2019年9月30日,aelf Enterprise 0.8.0 beta版正式发布。aelf Enterprise 0.8.0 beta是一个完备的区块链系统, 包含完备的区块链系统、开发套件、开发文档、以及配套的基础应用和基础服务。 ...

AELF开发者社区
今天
10
0
oracle 初始化数据库脚本

create user lpf identified by 123456; create tablespace lpf_ts_cms datafile '/opt/app/oracle/product/11.2.0/lpf.dbf' size 200M; alter user lpf default tablespace lpf_ts_cms; sel......

internetafei
今天
8
0
深入了解Redis底层数据结构

说明 说到Redis的数据结构,我们大概会很快想到Redis的5种常见数据结构:字符串(String)、列表(List)、散列(Hash)、集合(Set)、有序集合(Sorted Set),以及他们的特点和运用场景。不过它们是...

TurboSanil
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部