不同的文章似乎在说不同的事情,因为它们谈论的是不同类型的引用传递。
决定参数是否应该通过引用传递的主要因素是函数签名本身,自 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;
and $a->some_property
也会是42
。但是,如果您为$by_value
,仍然不会影响$a
.
直到 PHP 5.4,有一个extra通过引用传递参数的方法,这是“强制”引用行为在通话时。这意味着你可以写foo(&$a, &$b);
并“捕获”所做的更改$by_value
在 - 的里面foo()
功能。依赖于此通常是一个坏主意,因此它被删除了。 (它出现在 5.4 中是因为它原本打算在 PHP 6 中删除,但该项目被无限期搁置,较小的更改出现在 5.3 和 5.4 中)。
最后,函数可以return通过引用的变量(如手册中讨论过这里 http://php.net/references.return)。这有点繁琐,因为它实际上需要你把&
in twoplace:在函数声明的开头,表示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 引擎使用一种称为“写时复制”的技术来留下多个变量,这些变量恰好具有指向同一块内存的相同值,即使它们没有绑定为参考。事实上,参考分配一般defeats这种优化是由于引擎跟踪哪些变量处于写时复制状态的方式而实现的。