在PHP中按引用返回

Ibr*_*mar 25 php return reference

我尝试使用谷歌搜索,尝试了PHP文档,搜索SO以获得答案,但找不到任何令人满意的结果.我正在读一本书,其中作者使用了Return by Reference,但从未解释过它是什么.作者使用的代码是

function &getSchool() {
    return $this->school;
}
Run Code Online (Sandbox Code Playgroud)

有人可以用一个关于这个概念的例子用简单的词语来解释.

谢谢.

Jon*_*Jon 34

假设你有这个类:

class Fruit {
    private $color = "red";

    public function getColor() {
        return $this->color;
    }

    public function &getColorByRef() {
        return $this->color;
    }
} 
Run Code Online (Sandbox Code Playgroud)

该类有一个私有属性和两个允许您访问它的方法.一个按值返回(默认行为),另一个按引用返回.两者之间的区别在于:

  • 使用第一种方法时,您可以更改返回的值,并且这些更改不会反映在私有属性中,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"; 
Run Code Online (Sandbox Code Playgroud)

看到它在行动.

警告:我觉得有必要提一下,虽然它们确实具有合法用途,但它们之一是应该很少使用的功能之一,并且只有在您首先仔细考虑过任何替代方案时才能使用.经验不足的程序员倾向于过度使用引用,因为他们看到他们可以帮助他们解决特定问题而不会同时看到使用引用的缺点(作为一个高级功能,其细微差别远非显而易见).


src*_*der 15

简单的规则:如果你&在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;
Run Code Online (Sandbox Code Playgroud)

产量

$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
Run Code Online (Sandbox Code Playgroud)

参考文献很棒,但如果您不熟悉它们,请遵循以下规则:

  • 如果您正在处理大型数组或类似的非对象数据结构,则只考虑使用引用
  • 永远不要引用一个对象(如果可以避免它)
  • 如果值保存在对象的静态属性或属性中,则只允许函数通过引用传递(即,它不是函数内的临时变量)

例外显然是非常实用的用法(即当你真的想要共享一个值来简化操作它的代码时).

再次,从来没有参考对象(这是毫无意义的!)