$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. uvaLA4255 Guess BFS+拓扑排序

    算法指南白书 思路:“连续和转化成前缀和之差” #include <stdio.h> #include <string.h> #include <iostream> ...

  2. JavaScript高级程序设计36.pdf

    TreeWalker TreeWalker是NodeIterator的更高级的版本,除了包括nextNode()和previousNode()在内的相同功能外,这个类型还提供了用于不同方向上遍历DOM ...

  3. javascript排序 查找算法大全

    在pptv的实习结束了, 忙着找工作的事,顺便把数据结构的那本书重新复习了一遍.为了加深印象,特意把里面的常用的排序.查找算法用js写了一遍 具体的实例在我的github上,大家可以访问的: http ...

  4. php 燕十八 观察者模式代码例子

    <?php class user implements SplSubject { public $lognum; public $hobby; protected $observers=null ...

  5. java从mysql导出数据例子

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sq ...

  6. linux运维安全工具集合[持续更新中..]

    lynis 安全漏洞检测工具    https://cisofy.com/download/lynis/    https://cisofy.com/files/lynis-2.2.0.tar.gz ...

  7. Java三大主流框架概述(转载)

    转自:http://www.douban.com/note/320140839/ Struts.Hibernate和Spring是我们Java开发中的常用关键,他们分别针对不同的应用场景给出最合适的解 ...

  8. OpenGL中的投影使用

    OpenGL中的投影使用 在OpenGL中,投影矩阵指定了可视区域的大小和形状.对于正投影与透视投影这两种不同的投影类型,它们分别有各自的用途. 正投影 它适用于2D图形,如文本.建筑画图等.在它的应 ...

  9. 常用命令-eval简析

    www.2cto.com   1. 工作原理及用法   用法:eval command-line 原理:eval主要用在对参数的特殊处理上面的,一般的命令行,shell处理参数就只执行一遍,像转义和变 ...

  10. 5 Common Interview Mistakes that Could Cost You Your Dream Job (and How to Avoid Them)--ref

    There have been many articles on our site on software testing interviews. That is because, we, as IT ...