web-dev-qa-db-ja.com

PHP

グーグルを試し、PHPドキュメントを試し、Stack Overflowで答えを検索しましたが、満足のいくものは見つかりませんでした。著者がReturn by Referenceを利用した本を読んでいましたが、何を説明していませんでした。作者が使用したコードは

function &getSchool() {
    return $this->school;
}

誰かがこの概念についての例で簡単な言葉で説明できますか?.

26

次のクラスがあるとします。

class Fruit {
    private $color = "red";

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

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

このクラスには、プライベートプロパティと、それにアクセスできる2つのメソッドがあります。 1つは値(デフォルトの動作)で返され、もう1つは参照で返されます。 2つの違いは次のとおりです。

  • 最初の方法を使用する場合、戻り値に変更を加えることができます。実際にはプロパティの値のコピーを変更しているため、これらの変更はFruitのプライベートプロパティ内に反映されません。
  • 2番目の方法を使用すると、実際には戻ってきますFruit::$color --a 別の名前のエイリアス同じ変数。したがって、それを使って何かを行う場合(その内容の変更を含む)、実際には、プロパティの値に対して同じアクションを直接実行しています。

これをテストするためのコードは次のとおりです。

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"; 

実際の動作を参照

警告:参照は正当な用途はありますが、まれにしか使用されるべきではない機能の1つであることに言及する義務があると感じています。最初に代替案を慎重に検討した場合のみ。経験の浅いプログラマーは、参照を使用することの欠点を同時に認識せずに特定の問題を解決するのに役立つことがわかるため、参照を使いすぎる傾向があります(高度な機能として、そのニュアンスは明らかではありません)。

34
Jon

簡単なルール:PHPの関数名の前に_&_を配置すると、関数を呼び出すときに_&_を使用できます(つまり、関数ではなく変数であるかのように戻り値です。

それでおしまい。


PHP参照で返す)ではなく、「PHPで戻り値を参照できる」と考える方が簡単です。前述のように、単に_&_を配置してPHPこれが必要です。配置せずに$var =& somefunction()を実行しようとすると、「変数のみを参照で割り当てる必要があります」というエラーが表示されます。

ジョンの答えとの混乱を解消するため。実際には、1つは参照によって返され、もう1つは値によって返される2つの別個の関数を持つ必要はありません。いくつかのプロジェクトの慣習の外。 _&_のみは、参照によって戻ることを許可し、強制しません参照により戻ります。

例えば。参照と非参照の両方の割り当てに使用される同じ関数

_\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
_

参照は素晴らしいですが、それらに精通していない場合は、次のルールに従ってください。

  • 大きな配列または同様の非オブジェクトデータ構造を扱っている場合にのみ、参照の使用を検討してください
  • オブジェクトを参照しないでください(回避できる場合)
  • 値がオブジェクトの静的プロパティまたは属性で維持されている場合(つまり、関数内の一時変数ではない場合)にのみ、関数が参照渡しを許可します。

例外は明らかに非常に実用的な使用法です(つまり、実際に値を共有して、それを操作するためのコードを単純化する場合)。

繰り返しますが、オブジェクトを参照しないでください(無意味です!)

15
srcspider

あなたが投稿した例はおそらくPHP4以前のものです。 PHP5 +ではほとんどの場合、オブジェクトが自動的に自動的に返されるため、参照によってオブジェクトを返す必要はなくなりました。

参照による戻りは、関数を使用して参照をバインドする変数を見つける場合に役立ちます。パフォーマンスを向上させるために参照による戻りを使用しないでください。エンジンはこれを自動的に最適化します。正当な技術的理由がある場合にのみ、参照を返します。

PHP docs で参照を返す)を参照してください

3
six8