php - 我需要在 PHP 5.5.X 及更高版本中使用 & 符号吗?

标签 php pass-by-reference ampersand

我到处都是混合信号。

是否使用“&”符号通过引用传递变量?

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

但是像这样的线程让我想知道:
Call-time pass-by-reference deprecated?
PHP and ampersand

让我举个例子来表述我的问题。

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

function recurring_mailer_form($form, $form_state) 
{

}

是否与:

function recurring_mailer_form($form, &$form_state) 
{

}

?

最佳答案

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

决定参数是否应该通过引用传递的主要因素是函数签名本身,自 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()foo(&$a, &$b); 并“捕获”对 $by_value 所做的更改功能。依靠这个通常是一个坏主意,所以它被删除了。 (它出现在 5.4 中,因为它打算在 PHP 6 中删除,但该项目被无限期搁置,较小的更改出现在 5.3 和 5.4 中)。

最后,函数可以通过引用返回一个变量(如discussed in the manual here)。这有点繁琐,因为它实际上要求您将 & 放在两个 位置:在函数声明的开头,表示 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 引擎使用一种称为“写入时复制”的技术来保留多个恰好具有相同值的变量指向同一 block 内存,即使它们没有绑定(bind)为引用。事实上,由于引擎跟踪哪些变量处于写入时复制状态的方式,引用赋值通常打败这种优化。

关于php - 我需要在 PHP 5.5.X 及更高版本中使用 & 符号吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19847781/

相关文章:

php - JSON 的双重编码

javascript - 如何在 php 中获取 javascript 动态行值?

php - SQLITE PHP JavaScript?自动刷新,无需整个页面刷新

javascript - 从字符串中删除 BBCode URL 标记

php - 刷新 JWT 应该由 API 还是客户端负责?

c++ - const int* const fun(const int* const& p) const; 的含义

java - Java 是 "pass-by-reference"还是 "pass-by-value"?

c++ - & 符号 '&' 参数末尾的运算符

c++ - 为什么下面的代码在通过引用传递时不显示错误

.htaccess - modrewrite,变量中的符号