php - 有时我们在基于类的编码中在函数之前声明 "&"

标签 php copy-on-write reference

我正在为项目开发遵循基于类的编码。我最近看到有时我们将“&”放在函数名称之前。

举个例子..

而不是定义

function test()

定义如下

function &test()

“&”有什么特殊含义吗?

最佳答案

正如@philip 提到的,它是 return a reference :

来自上面的链接:

Note: Unlike parameter passing, here you have to use & in both places - to indicate that you want to return by reference, not a copy, and to indicate that reference binding, rather than usual assignment, should be done for $myValue.


PHP 将每个变量存储在 ZVAL 中容器。

来自上面的链接:

A zval container contains, besides the variable's type and value, two additional bits of information.The first is called "is_ref" and is a boolean value indicating whether or not the variable is part of a "reference set". With this bit, PHP's engine knows how to differentiate between normal variables and references. Since PHP allows user-land references, as created by the & operator, a zval container also has an internal reference counting mechanism to optimize memory usage. This second piece of additional information, called "refcount", contains how many variable names (also called symbols) point to this one zval container.


观察输出中变量的值:
考虑以下在返回值赋值处没有 & 的情况:

$b=0;
function &func ($name) {
  global $b;
  $b = 10;
  return $b;
  }
$a = func("myname");// no & at assignment
++$a ;
echo '<br/>$a= '.$a.' $b= ' .$b."<br/>";
xdebug_debug_zval('a'); echo "<br/>";

以上代码的输出:

$a= 11 $b= 10
a: (refcount=1, is_ref=0)=11 

虽然该函数通过引用返回,但该引用是针对返回值的 zval 容器的。现在,当我们试图分配返回值时,(比如在分配时没有 & )只有“refcount”会增加。其中“is_ref”不会被更改。当试图更改“存储返回值的变量”时,C.O.W (copy on write)发生并创建一个新的 zval 容器,使按引用返回无用。因此,您还需要在返回值的赋值处添加 &

在分配返回值时考虑以下带有 & 的内容:

$b=0;
function &func ($name) {
  global $b;
  $b = 10;
  return $b;
  }
$a =& func("myname");// & at assignment
++$a ;
echo '<br/>$a= '.$a.' $b= ' .$b."<br/>";
xdebug_debug_zval('a'); echo "<br/>";

输出:

$a= 11 $b= 11
a: (refcount=2, is_ref=1)=11 

关于php - 有时我们在基于类的编码中在函数之前声明 "&",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8664499/

相关文章:

php - CodeIgniter 和 Smarty

php - Doctrine - Symfony 查询错误

php - 对所有商品价格求和并将它们乘以 laravel 中的数据透视表

c - fork() 中的写时复制如何工作?

c++ - 在 C++ 中使用引用而不是指针有什么好处吗?

c - 错误未定义对 'WinMain@16' 的引用

java - 解析 JSON 数据时出错 - 异步任务

写时的 python 复制,真的吗?

c++ - Qt 未记录的方法 setSharable

rust - 为什么我不能对一个永远不会超出范围的值进行静态引用?