【1】引用是什么
不同语言中对引用的定义不一定是一样的,在 PHP 中引用其实是 可以用不同的名字访问用一个变量内容。
如 $a = 1; $b = &$a, 则可用使用 $b、$a 访问 1 ,指向的是内存中的内容。这就不像 C 语言那样,引用是实际的内存地址,也就是指针。
再举一个例子:在 Unix/Linux 中的文件名和文件本身, PHP中变量名对应目录条目,而变量内容对应文件本身。引用可以被看作是 Unix 文件系统中的硬链接。
【2】引用不是什么
上面解释了 PHP 中的引用是什么,这一节将描述 引用不是什么?先看一个代码片段:
<?php
function test(&$b)
{
$c = 2;
$b = & $c;
// 猜一下这里是输出 1 还是 2?
var_dump($a);
}
$a = 1;
test($a);
// 猜一下这里是输出 1 还是 2?
var_dump($a);
第一处输出是2,但第二处输出的 $a 还是 1,这是为什么?
例子中在形参那里用 & 符号把 $a 和 $b 绑定起来了,接着在函数体中把 $b 和 $c 绑定起来。但是在 PHP 中不可能通过引用机制将 $a 在函数体中绑定到其他的变量上。
这是因为在函数中并没有 $a, 存在的 $b 在这里是 $a 指向的内容。所以只有变量内容而没有调用符号表中的名字到值的绑定。
所以 PHP 中引用不是指针。
注意:
1)允许用两个变量来指向同一个内容。如 $a =& $b; 意味着 $a 和 $b 指向了同一个变量。$a 和 $b 在这里是完全相同的,这并不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一个地方。
2)如果在 foreach 语句中给一个具有引用的变量赋值,被引用的对象也被改变。
【3】引用传递
PHP 中引用传递是将一个变量通过引用传递给函数。且只有下面的两种情况:
# case 1
// 只需要在行参前加上 & 即可。
function foo(&$var)
{
// do something
}
$a = 5;
// 实参处不需要加 & 。
foo($a);
# case 2
// 从函数中返回的引用
function foo(&$var)
{
// do something
}
// 作为参数的函数需要加 &
function &bar()
{
$a = 5;
return $a;
}
foo(bar());
【4】引用返回
文档中描述:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。极其难理解,我的理解是把函数的返回和变量绑定起来,这样在修改变量的时候等同于修改了函数的返回值。
先看一个例子:
<?php
class Test {
public $a = 1;
public function getValue()
{
return $this->a;
}
}
$handle = new Test();
$value = $handle->getValue();
// 打印结果是 1。 符合预期的结果
echo $value;
// 这里给属性 $a 重新赋值为 2。
$handle->a = 2;
// 我们的预期是 2。 其实不然。这里还是 1。 在PHP中,这种情况还是 值返回。
echo $value;
// 若想能引用返回 需要是 $value = &$handle->getValueByQuote(); 这种形式。
// 如下
class Test {
public $a = 1;
public function &getValueByReference()
{
return $this->a;
}
}
$handle = new Test();
// 此时 value 就是 $this->a 的引用。
$value = &$handle->getValueByReference();
// 这里给属性 $a 重新赋值为 2。 等同给 $this->a 重新赋值。
$handle->a = 2;
// 所以这里打印得到 2.
echo $value;
通常情况下 ,引用返回是很少使用到的。
【4】取消引用
取消对一个变量的引用可使用 unset。如下例子:
<?php
$a = 1;
$b =& $a;
// 当 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。
// 不会 unset $b,只是 $a。类似 unix\Linux 下的 unlink。
unset($a);