$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. 找回linux丢失的磁盘空间

    最近一台服务器空间总是报警,磁盘空间不足. 使用 df 命令查看,磁盘空间耗用接近 100%,将机器上过期的数据以及日志清理掉,但是空间很快又是接近 100%. 使用 du 查看,想找出磁盘空间被耗用 ...

  2. Yii简单的基于角色的访问控制

    public function filters() { return array( 'accessControl', // perform access control for CRUD operat ...

  3. MySQL WorkBench中文教程

    在网上找到了一份MySQL WorkBench的教程,点此可以下载Work Bench教程(原文),为了便于学习和交流,请朋友帮忙翻译成了中文,点此可以下载Work Bench教程(中文翻译版). 具 ...

  4. 配置nginx如果获取不到图片 去另外一台服务器获取

    配置nginx服务器从一台服务器如果获取不到图片 从另外一台服务器中获取 location ^~ /uploads/ { root /data/weiwend/weiwang; try_files $ ...

  5. zookeeper与activemq最新存储replicatedLevelDB整合

    测试环境:三台VM虚拟机centos6.4 64位 mini版,IP分别为192.168.1.191/192/193. 测试目的:测试activemq的failover以及与zookeeper的整合 ...

  6. Java和Tomcat类加载机制

    转自:http://blog.csdn.net/codolio/article/details/5027423 加载类是运行程序的基础,了解Java和Tomcat的类加载机制对更有效地开发.调试Web ...

  7. 自己封装的C#操作redis公共类

    关于C#操作redis公共类,网上有很多版本,每个版本我都看了,发觉还是不够完美,都存在一个问题,只能操作单一的缓存数据库 redis指令支持上,这里可以自己去扩展,下面分享下我近期封装的一个redi ...

  8. SOA体系结构基础培训教程-规范标准篇

    引子:本文是<SOA体系结构基础培训教程>第3章<SOA标准与规范>课件,版权所有,转载请注明出处. 随着SOA在业界的应用日益广泛,SOA的标准化问题也成为各界日益关注的焦点 ...

  9. oracle7

    管理初始化参数 管理初始化参数(调优的一个重要知识点,凭什么可以对数据库进行调优呢?是因为它可以对数据库的一些参数进行修改修正) 初始化参数用于设置实例或是数据库的特征.oracle9i提供了200多 ...

  10. PureMVC(JS版)源码解析(三):Observer类

          上一篇博客中,我们讲到了Notification类(消息类),Notification(消息)是连接观察者(observer)和通知者(notifier)之间的桥梁.这一篇博客,主要是在代 ...