为什么我必须在函数调用中使用引用运算符(&)?
建立
我借用了一个我经常用于定制项目的开源CMS的功能。
它的目的对于这个问题并不重要,但如果你想知道它是一个简单的静态缓存,旨在减少数据库查询。 我可以在一个页面加载中调用getObject 10次,而不必担心会触发数据库10次。
码
该函数的简化版本如下所示:
function &staticStorage($name, $default_value = NULL)
{
static $data = array();
if (isset($data[$name])
{
return $data[$name];
}
$data[$name] = $default_value;
return $data[$name];
}
这个函数可以这样调用:
function getObject($object_id)
{
$object = &staticStorage('object_' . $object_id);
if ($object)
{
return $object;
}
// This query isn't accurate but that's ok it's not important to the question.
$object = databaseQuery('SELECT * FROM Objects WHERE id = @object_id',
array('@object_id => $object_id'));
return $object;
}
这个想法是,一旦我调用static_storage
,返回的值将更新静态存储,因为它被更改。
问题
我的兴趣在行$object = &staticStorage('object_' . $object_id);
注意函数前面的&
。 staticStorage
函数已经返回一个引用,所以我最初没有在函数调用之前包含引用操作符。 但是,如果没有函数调用之前的引用,它将无法正常工作。
我对指针的理解是,如果我返回一个指针,php会自动将该变量转换为一个指针$a = &$b
将导致$a
指向$b
的值。
这个问题
为什么? 如果函数返回一个引用,为什么我必须在函数调用之前使用引用运算符?
来自PHP文档
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.
http://php.net/manual/en/language.references.return.php
基本上,它帮助php解释器。 函数定义中的第一个用途是返回引用,第二个用于通过引用而不是值绑定到赋值。
通过在函数声明中放入&
,函数将返回返回值的内存地址。 分配,得到这个内存地址时,将其解释值作为一个int,除非明确告知,否则,这就是为什么第二&
需要使用赋值运算符。
编辑:正如@ringø下面指出的那样,它不返回内存地址,而是一个将被视为副本的对象(技术上写时拷贝)。
PHP文档解释了如何使用以及为什么返回引用的函数。
在您的代码中, getObject()
函数还需要一个&
(以及调用),否则引用将丢失,并且数据可用时基于PHP写时复制(返回的数据和源数据点都是相同的实际数据,直到其中一个数据发生变化=>具有不同寿命的两个数据块)
这不起作用(语法错误)
$a = array(1, 2, 3);
return &$a;
这不按预期工作(没有参考返回)
$a = array(1, 2, 3);
$ref = &$a;
return $ref;
并且不需要像上面所说的那样将&
添加到函数调用中,也不会返回任何参考。
关于为什么......这个问题似乎没有一致的答案。
&
缺少PHP将数据视为不是引用(比如返回一个数组),而没有任何警告 PHP在这些年来发展起来,但仍然继承了一些最初的糟糕设计选择。 这似乎是其中之一(此语法是很容易出错的一个可以轻易错过一个&
...并提前没有警告......;还有为什么不直接返回像一个基准return &$var;
PHP取得了一些进展,但依然存在,可怜的设计痕迹依然存在。
您也可能对上面链接的文档的这一章感兴趣
不要使用按引用返回来提高性能。 引擎会自动优化它。 只有当你有合理的技术理由才能返回参考。
最后,最好不要在C和PHP引用中的指针之间进行等价(Perl在这方面比PHP更接近)。 PHP在实际指向数据和变量以及引用点之间增加了一层,而不是实际数据。 但是参考不是一个指针。 如果$a
是一个数组而$b
是对$a
的引用,则使用$a
或$b
来访问数组是等同的。 有没有解引用语法,一个*$b
在C.例如像$b
应该被视为一个别名$a
。 这也是一个函数只能返回一个变量引用的原因。
上一篇: Why do I have to use the reference operator (&) in a function call?