$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. 白帽子讲Web安全2.pdf

    XSS构造技巧 利用字符编码: var redirectUrl="\";alert(/XSS/);"; 本身没有XSS漏洞,但由于返回页面是GBK/GB2312编码的“% ...

  2. Bzoj 3505: [Cqoi2014]数三角形 数论

    3505: [Cqoi2014]数三角形 Time Limits: 1000 ms  Memory Limits: 524288 KB  Detailed Limits   Description

  3. install Active Directory域控制器

    设置Active Directory域控制器 正如我们在网络与系统配置专题文章中所提到的那样,我们已将两部服务器设置为对应于内部域“intdomain.com”的Active Directory域控制 ...

  4. 1 storm基本概念 + storm编程规范及demo编写

    本博文的主要内容有 .Storm的单机模式安装 .Storm的分布式安装(3节点)   .No space left on device .storm工程的eclipse的java编写 http:// ...

  5. 【Java重构系列】重构31式之搬移方法

    重构第二式:搬移方法 (Refactoring 2: Move Method) 毋容置疑,搬移方法(Move Method)应该是最常用的重构手段之一,正因为太常用而且较为简单,以至于很多人并不认为它 ...

  6. mongodb数据库连接池(java版)

    mongodb数据库接口的设计 package storm.db; import java.util.ArrayList; import com.mongodb.DB; import com.mong ...

  7. Velocity 的工作原理

    原文出处:http://www.blogjava.net/jackybu/articles/8803.html 这个程序很简单,但是它能让你清楚的了解Velocity的基本工作原理.程序中其他部分基本 ...

  8. 前端学习-使用JS库Leaflet.js生成世界地图并获取标注地址经纬度。

    介绍:Leaflet是一个开源的JavaScript库,对移动端友好且对地图有很好的交互性. 大小仅仅只有 33 KB, 同时具有大多数地图所需要的特点. Leaflet设计的非常简单易懂, 同时具有 ...

  9. HTML快速参考

    HTML 模版 html> <head> <meta charset="utf-8"/> <title>html template< ...

  10. Android——打造万能适配器(CommonAdapter)

    List<T> : ListView -> Adapter extends BaseAdapter -> ViewHolder ViewHolder CommonAdaper ...