在开始本节内容前,我们先来看看一道还算比较常见的PHP面试题:
1 |
$arr = array ( '1' , '2' , '3' ); |
2 |
3 |
foreach ( $arr as & $v ){ |
4 |
} |
5 |
6 |
foreach ( $arr as $v ){ |
7 |
} |
8 |
9 |
var_dump( $arr ); |
猜一下,运行的结果会是什么呢?熟悉PHP的同学可能已经知道结果了:
1 |
array |
2 |
0 => string '1' (length=1) |
3 |
1 => string '2' (length=1) |
4 |
2 => &string '2' (length=1) |
那么为什么是1,2,2呢。让我们一步步来看:
我们知道对数组执行foreach循环时,是通过移动数组内部指针来实现的。对于上面的例子:当foreach循环结束的时候,由于$v为引用变量,所以$v 与 $arr[ 2 ] 指向了同一个地址空间(共享变量值),之后对$v的任何修改都会直接反映到数组$a中。
要不我们在程序中加入调试代码,看看运行过程的情况吧。
1 |
$arr = array ( '1' , '2' , '3' ); |
2 |
3 |
foreach ( $arr as & $v ){ |
4 |
} |
5 |
6 |
foreach ( $arr as $v ){ |
7 |
var_dump( $arr ); |
8 |
echo "<br/>" ; |
9 |
} |
程序运行的结果是:
01 |
array |
02 |
0 => string '1' (length=1) |
03 |
1 => string '2' (length=1) |
04 |
2 => &string '1' (length=1) |
05 |
06 |
array |
07 |
0 => string '1' (length=1) |
08 |
1 => string '2' (length=1) |
09 |
2 => &string '2' (length=1) |
10 |
11 |
array |
12 |
0 => string '1' (length=1) |
13 |
1 => string '2' (length=1) |
14 |
2 => &string '2' (length=1) |
简单解释一下:
1. 引用类似于指针,但是不同于指针。
下面的操作让 $a 和 $b 指向了同一个内存块,值为 “str”
1 |
$a = "str" ; |
2 |
$b = & $a ; |
3 |
4 |
echo $a ; |
5 |
echo '<br />' ; |
6 |
echo $b ; |
试下更改$a和$b中任何一个元素的值。另外一个值都为随之改变:
1 |
$a = "str" ; |
2 |
$b = & $a ; |
3 |
4 |
$b = "www.nowamagic.net" ; |
5 |
6 |
echo $a ; |
7 |
echo '<br />' ; |
8 |
echo $b ; |
程序运行结果为:
1 |
www.nowamagic.net |
2 |
www.nowamagic.net |
2. 引用作为函数参数传递时,是可以被函数内部更改的:
01 |
$a = "str" ; |
02 |
$b = & $a ; |
03 |
04 |
function change(& $a ){ |
05 |
$a = "www.nowamagic.net" ; |
06 |
} |
07 |
08 |
change( $a ); |
09 |
10 |
echo $a ; |
11 |
echo '<br />' ; |
12 |
echo $b ; |
程序运行结果为:
1 |
www.nowamagic.net |
2 |
www.nowamagic.net |
3. unset只会删除变量。并不会清空变量值对应的内存空间:
1 |
$a = "str" ; |
2 |
$b = & $a ; |
3 |
4 |
unset( $b ); |
5 |
6 |
echo $a ; |
7 |
echo '<br />' ; |
8 |
echo $b ; |
程序运行结果为:
1 |
str |
2 |
Notice: Undefined variable: b |