在 PHP 中通过引用返回
Posted
技术标签:
【中文标题】在 PHP 中通过引用返回【英文标题】:Return by reference in PHP 【发布时间】:2011-11-19 07:35:06 【问题描述】:我尝试了谷歌搜索,尝试了 php 文档,搜索了 Stack Overflow 的答案,但找不到任何令人满意的东西。我正在读一本书,其中作者使用了Return by Reference,但从未解释过它是什么。作者使用的代码是
function &getSchool()
return $this->school;
有人可以用简单的话解释一下这个概念吗?
【问题讨论】:
PHP docs 是对此的最终答案——请务必浏览所有“参考说明”部分。 Cmon Jon,我已经说过我已经阅读了文档,并且承认我从那里并没有很好地理解它。这就是我在这里问的原因,如果您有任何版本要解释,我将不胜感激:) Jon 提供的链接通过示例很好地解释了这一点。 @IbrahimAzharArmar:通过示例代码和解释添加了完整答案,希望对您有所帮助:) 【参考方案1】:假设你有这个类:
class Fruit
private $color = "red";
public function getColor()
return $this->color;
public function &getColorByRef()
return $this->color;
该类有一个私有属性和两个允许您访问它的方法。一个按值返回(默认行为),另一个按引用返回。两者的区别在于:
使用第一种方法时,您可以对返回的值进行更改,这些更改不会反映在Fruit
的私有属性中,因为您实际上是在修改属性值的副本。
当使用第二种方法时,您实际上得到的是 Fruit::$color
的别名——一个不同的名称,您通过它来引用 相同的变量。因此,如果您对它进行任何操作(包括修改其内容),您实际上是在直接对属性的值执行相同的操作。
这里有一些代码来测试它:
echo "\nTEST RUN 1:\n\n";
$fruit = new Fruit;
$color = $fruit->getColor();
echo "Fruit's color is $color\n";
$color = "green"; // does nothing, but bear with me
$color = $fruit->getColor();
echo "Fruit's color is $color\n";
echo "\nTEST RUN 2:\n\n";
$fruit = new Fruit;
$color = &$fruit->getColorByRef(); // also need to put & here
echo "Fruit's color is $color\n";
$color = "green"; // now this changes the actual property of $fruit
$color = $fruit->getColor();
echo "Fruit's color is $color\n";
See it in action.
警告:我觉得有必要提一下,虽然它们确实有合法用途,但它们是那些应该很少使用的功能之一,只有在你仔细考虑过任何替代品的情况下才能使用首先。经验不足的程序员倾向于过度使用引用,因为他们认为可以帮助他们解决特定问题,同时又不会看到使用引用的缺点(作为一项高级功能,其细微差别远非显而易见)。
【讨论】:
另一方面,所有这些都在文档中有效,但是当接收端没有提到&符号时会发生什么,以及如何在类中禁用按值复制?例如。对于单例类。因为如果您必须指望调用者表现良好,那么知道您想要返回一个值没有多大意义,是吗?【参考方案2】:简单规则:如果您在 PHP 中的函数名称前放置 &
,您可以在调用函数(即它的返回值)时使用 &
,就好像它是一个变量而不是一个函数。
就是这样。
更容易将其视为“PHP 允许您引用返回值”,而不是 PHP 通过引用返回。如上所述,您只需放置一个 &
来告诉 PHP 您想要这个,如果您不放置它并尝试对 $var =& somefunction()
执行此操作,您将收到错误“仅应通过引用分配变量”。
为了消除对 Jon 的回答的一些困惑。实际上没有必要有两个单独的函数,一个按引用返回,一个按值返回;在某些项目约定之外。 &
仅允许它通过引用返回,它不强制它通过引用返回。
例如。用于引用和非引用分配的相同函数
\header('content-type: text/plain');
class Demo
protected $example = 'original value';
function & example()
return $this->example;
$demo = new Demo;
#1 - pass by value
$var1 = $demo->example();
$var1 = 'var1 value';
echo '$demo->example() => '.$demo->example().PHP_EOL;
echo PHP_EOL;
#2 - pass by reference
$var2 =& $demo->example();
$var2 = 'var2 value';
echo '$demo->example() => '.$demo->example().PHP_EOL;
echo '$var1 => '.$var1.PHP_EOL;
echo '$var2 => '.$var2.PHP_EOL;
echo PHP_EOL;
#3 - altering other references
$var3 =& $demo->example();
$var3 = 'var3 value';
echo '$demo->example() => '.$demo->example().PHP_EOL;
echo '$var1 => '.$var1.PHP_EOL;
echo '$var2 => '.$var2.PHP_EOL;
echo '$var3 => '.$var3.PHP_EOL;
echo PHP_EOL;
exit;
输出
$demo->example() => original value
$demo->example() => var2 value
$var1 => var1 value
$var2 => var2 value
$demo->example() => var3 value
$var1 => var1 value
$var2 => var3 value
$var3 => var3 value
参考很好,但是如果您不熟悉它们,请遵循以下规则:
仅在处理大型数组或类似的非对象数据结构时才考虑使用引用 永远不要引用对象(如果可以避免的话) 仅当值保留在对象的静态属性或属性中时才允许函数通过引用传递(即,它不是函数内部的临时变量)异常显然是非常实用的用途(即,当您真正想要共享一个值以简化操作它的代码时)。
再次,永远不要引用对象(这毫无意义!)
【讨论】:
【参考方案3】:您发布的示例可能来自 PHP4 或更早版本。不再需要通过引用返回对象,因为在 PHP5+ 中它们几乎总是以这种方式自动完成。
当你想使用一个函数来返回引用时很有用 找到一个引用应该绑定到哪个变量。不使用 通过引用返回以提高性能。发动机将 自动对其进行优化。仅在以下情况下返回引用 您有正当的技术理由这样做。
见return references in PHP docs
【讨论】:
我已经说过我已经阅读过文档,这对我没有任何解释。我想了解更多。 在某些情况下,通过引用返回可能很好,但我是一个强有力的对手。另见我的博客:schlueters.de/blog/archives/125-Do-not-use-PHP-references.html以上是关于在 PHP 中通过引用返回的主要内容,如果未能解决你的问题,请参考以下文章