使用引用执行有三种基本操作: 引用赋值 、 传引用 、 引用返回 。 本节介绍这些操作,并提供进一步阅读的链接。
PHP 的引用允许用两个变量来指向同一个内容。意思是,当这样做时:
<?php
$a =& $b;
?>
注意:
$a 和 $b 在这里是完全相同的,这并不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一个地方。
注意:
如果对一个未定义的变量进行引用赋值、引用参数传递或引用返回,则会自动创建该变量。
示例 #1 对未定义的变量使用引用
<?php
function foo(&$var) { }
foo($a); // 创建 $a 并赋值为 null
$b = array();
foo($b['b']);
var_dump(array_key_exists('b', $b)); // bool(true)
$c = new stdClass;
foo($c->d);
var_dump(property_exists($c, 'd')); // bool(true)
?>
同样的语法可以用在返回引用的函数中:
<?php
$foo =& find_var($bar);
?>
在函数内使用相同的语法 不 通过引用返回将会产生错误, 就像将它与 new 运算符的结果一起使用一样。 正如 对象和引用 中所述, 尽管对象是通过指针传递的,但是它们与引用不同。
如果在一个函数内部给一个声明为 global
的变量赋于一个引用,该引用只在函数内部可见。可以通过使用
$GLOBALS 数组避免这一点。
示例 #2 在函数内引用全局变量
<?php
$var1 = "Example variable";
$var2 = "";
function global_references($use_globals)
{
global $var1, $var2;
if (!$use_globals) {
$var2 =& $var1; // 仅在函数内部可见
} else {
$GLOBALS["var2"] =& $var1; // 全局上下文可见
}
}
global_references(false);
echo "var2 is set to '$var2'\n"; // var2 is set to ''
global_references(true);
echo "var2 is set to '$var2'\n"; // var2 is set to 'Example variable'
?>
global $var;
当成是 $var
=& $GLOBALS['var'];
的简写。从而将其它引用赋给
$var
只改变了本地变量的引用。
注意:
如果在 foreach 语句中给一个具有引用的变量赋值,被引用的对象也被改变。
示例 #3 引用与 foreach 语句
<?php
$ref = 0;
$row =& $ref;
foreach (array(1, 2, 3) as $row) {
// 做点什么
}
echo $ref; // 3 - 迭代数组的最后一个元素
?>
虽然不是严格意义上的引用赋值,但使用语言构造
array()
创建的表达式也可以通过在要添加的数组元素加上 &
前缀来表现为这样。例如:
<?php
$a = 1;
$b = array(2, 3);
$arr = array(&$a, &$b[0], &$b[1]);
$arr[0]++; $arr[1]++; $arr[2]++;
/* $a == 2, $b == array(3, 4); */
?>
但是请注意,数组内的引用具有潜在的危险。 在右侧引用正常的赋值(不是通过引用)不会将左侧变为引用, 但是数组内部的引用会保留在这些正常赋值中。 这也适用于调用函数时按值传递数组的情况。例如:
<?php
/* 标量变量赋值 */
$a = 1;
$b =& $a;
$c = $b;
$c = 7; //$c 不是引用;不会改变 $a 或者 $b
/* 数组变量赋值 */
$arr = array(1);
$a =& $arr[0]; //$a 和 $arr[0] 设置了相同的引用
$arr2 = $arr; //不是引用赋值!
$arr2[0]++;
/* $a == 2, $arr == array(2) */
/* 尽量 $arr 不是引用,但是它的内容已经更改! */
?>
引用做的第二件事是用引用传递变量。这是通过在函数内建立一个本地变量并且该变量在呼叫范围内引用了同一个内容来实现的。例如:
<?php
function foo(&$var)
{
$var++;
}
$a=5;
foo($a);
?>
引用做的第三件事是引用返回。