使用以下代码:
$a[1]=1;
$a[2]=& $a[1];
$b=$a;
$b[2]=7;
print_r($a);
我原本期望输出结果是1
,因为$a
并没有被引用赋值给$b
($a = & $b
),但实际输出结果是7
。为什么呢?
php > var_dump($a);
array(2) {
[1]=>
&int(1)
[2]=>
&int(1)
}
php > $b=$a;
php > var_dump($b);
array(2) {
[1]=>
&int(1)
[2]=>
&int(1)
}
以下是一个通过引用复制数组的例子:
php > $c[1] = 1;
php > $c[2] =& $c[1];
php > var_dump($c);
array(2) {
[1]=>
&int(1)
[2]=>
&int(1)
}
php > $d =& $c;
php > var_dump($d);
array(2) {
[1]=>
&int(1)
[2]=>
&int(1)
}
php > $d = array(3,4,5);
php > var_dump($c);
array(3) {
[0]=>
int(3)
[1]=>
int(4)
[2]=>
int(5)
}
php > var_dump($d);
array(3) {
[0]=>
int(3)
[1]=>
int(4)
[2]=>
int(5)
}
正如你所见,数组变量(而不是元素)本身就是一个引用,因此修改 $d
会影响到 $c
。重新分配 $b
本身对 $a
没有影响。
$a[2]=& $a[1];
时,表示 $a 的两个元素现在都持有同一个变量。当您执行 $b = $a 时,$b 和 $a 是不同的变量,但它们内部的所有4个元素指向同一个变量!尝试执行 $b[3] = 7
并查看是否复制到 $a - 因为 $b 和 $a 是不同的,但 $b[2] 和 $a[2] 不是!
引用可能会有些混乱,抱歉。除非必须使用它们,否则请避免使用。
这帮助我理解了什么是引用:
http://www.php.net/manual/en/features.gc.refcounting-basics.php
而且使用xdebug进行调试有助于解决有趣的案例
例如,您可以"避免"使用私有属性:
class c{ private $a = 42; function &a(){ return $this->a; } function print_a(){ echo $this->a; } } $c = new c; $d = &$c->a(); echo $d; $d = 2; $c->print_a();
或者在函数中引用传递参数(未声明为引用):
function f1(&$s) { $s++; } function f2($s) { $s--; } $s1 = 1; $s2 = 3; f1($s1); f2(&$s2); echo $s1.$s2;
此外,foreach循环也可以使用引用传递:
$a = array(1,2,3); foreach ( $a as $key => &$value ) { $value = 1; } $value = 2;