8

我到处都收到混合信号。

我是否使用与号通过引用传递变量?

以下链接似乎告诉我它已被弃用且不再需要: http:
//gtk.php.net/manual/en/html/tutorials/tutorials.changes.references.html

但是像这样的线程让我想知道:
不推荐使用调用时传递引用?
PHP 和 & 符号

让我以我的问题为例。

如果我使用 PHP 5.5.5 创建一个函数:

function recurring_mailer_form($form, $form_state) 
{

}

是否与以下内容相同:

function recurring_mailer_form($form, &$form_state) 
{

}

?

4

3 回答 3

23

不同的文章似乎在说不同的事情的原因是它们在谈论不同类型的传递引用。

决定一个参数是否应该通过引用传递的主要因素是函数签名本身,自 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 引擎使用一种称为“写入时复制”的技术来保留多个变量,这些变量恰好具有指向同一块内存的相同值,即使它们没有绑定为参考。事实上,由于引擎跟踪哪些变量处于写时复制状态的方式,引用分配通常会破坏这种优化。

于 2013-11-07T22:46:25.967 回答
3

不它不是。

  • 对象总是作为引用自动传递(信息!有关其他重要信息,请参见下文!)

  • 将参数声明为引用必须发生在函数定义中:

    function test(&$var) {}
    

    不是在调用它的时候:

    // wrong
    $var = '123';
    test(&$var);
    


如果像往常一样传递对象,则可以更改对象的状态(属性)。
假设这$obj是一个类的实例,TestClass其中包含一个名为的成员变量hello点击此处查看 Ideone.com 上的完整示例):

function modify($obj) { $obj->hello = 'world (modified)!'; }

$obj->hello = 'world';
modify($obj);
var_dump($obj->hello);  // outputs "world (modified!)"

这应该是不言自明的。现在,使用相同的代码但分配另一个值来$obj修改对象的状态不会导致修改(→ Ideone.com):

function modify($obj) { $obj = 42; }
// ...
var_dump($obj->hello);  // outputs "world"

只有明确地接受参数作为参考,我们才能完全改变变量的内容(→ Ideone.com):

function modify(&$obj) { $obj = 42; }
// ...
var_dump($obj);         // outputs "42"
于 2013-11-07T22:18:38.277 回答
1

不,那些不一样。PHP 5.4+ 只是在调用时通过检查声明来检测调用函数时是否需要引用。

所以不,不推荐使用,因为如果这是您的预期用途,您需要在函数声明中使用引用运算符。

于 2013-11-07T22:17:54.663 回答