不同的文章似乎在说不同的事情的原因是它们在谈论不同类型的传递引用。
决定一个参数是否应该通过引用传递的主要因素是函数签名本身,自 PHP 4 以来,它的基本原理没有改变。考虑这个例子:
function foo( $by_value, &$by_reference ) { /* ... */ }
$a = 1; $b = 2;
foo( $a, $b );
在这里,外部变量$a
按值传递给函数,就好像它被分配为$by_value = $a;
- 更改为$by_value
无法影响$a
。然而,变量$b
是通过引用传递的;就像形式的赋值一样,$by_reference =& $b;
这意味着有一个变量被两个名称引用,并且对一个变量的任何赋值都将作为对两者的赋值。
如果您按值传递“普通”值(字符串、数字或数组),则它的值只是复制到新变量中。从 PHP 5 开始:但是,如果您按值传递对象,则会发生一些稍微不同的事情 - 复制的“值”只是指向同一对象的指针。这意味着如果$a
是一个对象,您可以调用$by_value->some_property = 42;
并且$a->some_property
也将是42
。但是,如果您为 分配了一些新值$by_value
,它仍然不会影响$a
。
在 PHP 5.4 之前,还有一种通过引用传递参数的额外方法,即在调用时“强制”引用行为。这意味着您可以编写foo(&$a, &$b);
和“捕获”$by_value
对函数内部所做的更改foo()
。依靠这个通常是一个坏主意,所以它被删除了。(它登陆 5.4 是因为它打算在 PHP 6 中删除,但该项目被无限期搁置,较小的更改登陆 5.3 和 5.4)。
最后,函数可以通过引用返回一个变量(如这里的手册中所讨论的)。这有点繁琐,因为它实际上需要你放在&
两个地方:在函数声明的开头,说return
应该是“返回这个变量引用”而不是“返回这个值”;在调用它的代码中,为该引用分配一个变量,而不仅仅是复制它的值。这是一个愚蠢的例子,它结合了引用参数和引用返回(两者不必一起,这只是一个例子):
function &bar(&$some_param) { return $some_param; }
$a = 1;
$b =& bar($a);
// $b and $a now point at the same variable, not just the same value
// it was passed into and out of a function, and assigned to a new variable,
// but all those operations were by reference
请注意,许多人错误地认为通过引用传递变量会给他们带来性能优势,这通常是他们使用调用时传递引用的唯一原因。这实际上通常是错误的,因为支持 PHP 的 Zend 引擎使用一种称为“写入时复制”的技术来保留多个变量,这些变量恰好具有指向同一块内存的相同值,即使它们没有绑定为参考。事实上,由于引擎跟踪哪些变量处于写时复制状态的方式,引用分配通常会破坏这种优化。