$a = array('a','b','c');
foreach($a as &$v){} foreach($a as $v){ }
var_dump($a);

现在。不要打开浏览器,猜测一下。输出的结果是什么?

对引用比较了解的童鞋可能已经看出来了。正确答案是: array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> &string(1) "b"}  也就是a,b,b.  如果你猜测的是a,b,c的话。 那么关于引用,你还要查阅一下相关的资料:http://www.php.net/manual/zh/language.references.php

那么为什么是a,b,b呢。让我们一步步来看:

我们知道对数组执行foreach循环时,是通过移动数组内部指针来实现的(关于更多细节,可以阅读php源码)。因而对于本文中的例子:当foreach循环结束的时候,由于$v为

引用变量,因而$v 与 $a[ 2 ] 指向了同一个地址空间(共享变量值),因而之后对$v的任何修改都会直接反映到数组$a中。我们可以对例子加上调试代码,便会一清二楚,例如我们在第二次循环内部,加上var_dump($a),测试每次循环时a的值的变化:

$a = array('a','b','c');
foreach($a as &$v){} foreach($a as $v){
var_dump($a);
echo "<br/>";
}
var_dump($a);

运行代码。结果为:

array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> &string(1) "a" }
array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> &string(1) "b" }
array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> &string(1) "b" }
array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> &string(1) "b" }

画个图:可以更加清晰看出来:(图中"$v指向了$a[2]"并不准确。应该是:$v与$a[2]指向了同一个地方)

关于引用的几点简单解释:

1.引用类似于指针,但是不同于指针。

例如对于引用:

$a = "str";
$b = &$a;//<var class="varname"><var class="varname"> $a</var></var> 和 <var class="varname"><var class="varname">$b</var></var> 指向了同一个地方

一个简单的示意图如下:

那么此时更改$a和$b中任何一个元素的值。另外一个值都为随之改变:

$a = "str";
$b = &$a;
$b = "sssss";
echo $a;

2.unset只会删除变量。并不会清空变量值对应的内存空间:(这是与指针不同的地方)

$a = "str";
$b = &$a;
unset($b);
echo $a;

3.引用作为函数参数传递时,是可以被函数内部更改的:

function change(&$a){
if(is_array($a)){
$a = array();
}
}
$test = range(1,10);
change($test);
print_r($test);

基于以上几点,在编码的过程中,要小心使用引用。防止陷入莫名其妙的尴尬。

ps:理解了么?试试这道题:

$a = range(1,3);
foreach($a as &$b){
$b *= $b;
} foreach( $a as $b){
echo $b;
}

猜猜看,输出是什么?。

【PHP】 foreach循环中变量引用的一道面试题的更多相关文章

  1. C#在foreach循环中修改字典等集合出错的处理

    C#在foreach循环中修改字典等集合出错:System.InvalidOperationException: Collection was modified; enumeration operat ...

  2. C#不允许在foreach循环中改变数组或集合中元素的值(注:成员的值不受影响)

    C#不允许在foreach循环中改变数组或集合中元素的值(注:成员的值不受影响),如以下代码将无法通过编译. foreach (int x in myArray) { x++; //错误代码,因为改变 ...

  3. js循环函数中的匿名函数和闭包问题(匿名函数要用循环中变量的问题)

    js循环函数中的匿名函数和闭包问题(匿名函数要用循环中变量的问题) 一.总结 需要好好看下面代码 本质是因为匿名函数用到了循环中的变量,而普通方式访问的话,匿名函数的访问在循环之后,所以得到的i是循环 ...

  4. 「译」forEach循环中你不知道的3件事

    前言 本文925字,阅读大约需要7分钟. 总括: forEach循环中你不知道的3件事. 原文地址:3 things you didn't know about the forEach loop in ...

  5. Java中有关构造函数的一道笔试题解析

    Java中有关构造函数的一道笔试题解析 1.详细题目例如以下 下列说法正确的有() A. class中的constructor不可省略 B. constructor必须与class同名,但方法不能与c ...

  6. 16.1 foreach 循环中捕获变量的变化

    在 foreach 循环内的匿名函数(通常为Lambda表达式)中捕获循环 变量时要格外小心.代码清单16-1就展示了这样一个简单的示例,它看上去似乎会输出 x . y . z . string[] ...

  7. 注意for循环中变量的作用域-乾颐堂

    1 2 for e in collections:     pass 在for 循环里, 最后一个对象e一直存在在上下文中.就是在循环外面,接下来对e的引用仍然有效. 这里有个问题容易被忽略,如果在循 ...

  8. 注意for循环中变量的作用域

    for e in collections: pass 在for 循环里, 最后一个对象e一直存在在上下文中.就是在循环外面,接下来对e的引用仍然有效. 这里有个问题容易被忽略,如果在循环之前已经有一个 ...

  9. 关于“foreach循环”中遇到的几个问题总结

    1.列表页面用"foreach循环"的时候数据没有显示,此时需要检查你对象模型中属性的首字母是否大写,切记不能大写(本人在做一个项目的时候,对象模型是别人建立的,属性首字母大写了, ...

随机推荐

  1. Java ThreadLocal深度解析

    首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的.各 ...

  2. 广州Uber优步司机奖励政策(2月1日~2月7日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  3. 什么时候使用Shell

    因为Shell似乎是各UNIX系统之间通用的功能,并且经过了POSIX的标准化.因此,Shell脚本只要“用心写”一次,即可应用到很多系统上.因此,之所以要使用Shell脚本是基于: 简单性:Shel ...

  4. HTML5 UTF-8 中文乱码

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. Javascript数据类型——undefined和null的异同

    Javascript的基本数据类型中有undefined和null两种只有一个值得特殊数据类型.其中undefined表示未被初始化,不是为声明.而null表示一个空对象指针,而这也是使用typeof ...

  6. sql中时间的一些特殊转换

    1.修改时间的秒和微秒 create table a (Dtime datetime);insert into aselect '2013-08-30 17:59:35' union allselec ...

  7. IO(Input Output)流__字节流

    续: ------->>>>字节流 IntputStream  OutputStream 需求:想要操作图片数据,就需要用到字节流. 读写操作: FileOutputStrea ...

  8. Linux 上的游戏 Supertuxkart

    Linux 上玩游戏 Supertuxkart 中午休息的时候,打开Supertuxkart游戏,这个是GNU下的一款3D赛车游戏,制作精美,玩法简单.最有趣的是,我连接笔记本的外接键盘被侦测出来是M ...

  9. (9/18)重学Standford_iOS7开发_动画、自动布局_课程笔记

    最近开始实习,没多少时间更新了=_= 第九课: 1.上节课demo:Dropit完整实现 https://github.com/NSLogMeng/Stanford_iOS7_Study/commit ...

  10. asp.net采用OLEDB方式导入Excel数据时提示:未在本地计算机上注册"Microsoft.Jet.OLEDB.4.0" 提供程序"

    笔者在项目中做做了一个从Excel表格中导入数据的模块.大体上asp.net项目中导入Excel大体分成三类: 1)采用c#内置方案System.Data.OleDb(限制较小, 通用) 2)采用Ex ...