朋友昨天去金山面试PHP开发时遇到的一道面试题,是关于引用和foreach循环的。很基础的一道题
废话不多说,直接看代码:
$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" }
关于引用的几点简单解释:
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;
$a = "str"; $b = &$a; unset($b); echo $a;
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; }猜猜看,输出是什么?。