5

重複の可能性:
PHPでは、誰かがクローン作成とポインター参照を説明できますか?

http://php.net/manual/en/language.oop5.references.phpによると

よく言及されるPHP5OOPの重要なポイントの1つは、「オブジェクトはデフォルトで参照によって渡される」ということです。これは完全には真実ではありません。このセクションでは、いくつかの例を使用して、その一般的な考え方を修正します。

PHP参照はエイリアスであり、2つの異なる変数が同じ値に書き込むことができます。PHP 5以降、オブジェクト変数にはオブジェクト自体が値として含まれなくなりました。これには、オブジェクトアクセサが実際のオブジェクトを見つけることができるオブジェクト識別子のみが含まれています。オブジェクトが引数によって送信されたり、返されたり、別の変数に割り当てられたりする場合、異なる変数はエイリアスではありません。同じオブジェクトを指す識別子のコピーを保持します。

オブジェクトがエイリアスまたはハンドラーによって渡される場合、どのような状況で実際に参照によって渡されますか?

myFunc($obj); // Pass by alias/handler

myFunc(& $obj); // Pass by reference (when would you do this?)

myFunc(clone $obj); // Create a new object

これらのそれぞれの異なるユースケースは何ですか?

4

3 に答える 3

2

これらのそれぞれの異なるユースケースは何ですか?

すでに3つの異なるユースケースに名前を付けています。

  1. パラメータとしてオブジェクトを渡す
  2. パラメータとしてエイリアスを渡す
  3. オブジェクトクローンをパラメータとして渡す

当然、特定のケースを実行する必要がある場合は、これら3つのことをそれぞれ実行します。通常、必要なのは99.9%の1つだけです。必要に応じて、残りの0.1%を実行します。

小さな例としてのパラメーターとしての変数エイリアスの例的なユースケース(コメントで求められている

class VarFreezer
{
    private $alias;
    private $value;
    public function __construct(&$object) {
        $this->alias = &$object;
        $this->value = $object;
    }
    public function restore()
    {
        $this->alias = $this->value;
    }
}

$var = new stdClass();
$var->value = 'I am an object now.';

$freezer = new VarFreezer($var);

$var = 'I am a string now.';

$freezer->restore();

var_dump($var);
于 2012-07-19T15:17:36.957 に答える
2

メソッドにオブジェクトを指定すると、既存のオブジェクトへの参照が渡されるため、呼び出し元のスコープに変数があり、メソッドのスコープにメソッドパラメーター変数が両方とも同じオブジェクトを参照しています。

&を明示的に使用して、配列などのプリミティブへの参照を指定し、呼び出されたメソッドが元の配列のデータを変更できるようにすることができます。あなたが言ったように、オブジェクトの場合、これは最近のデフォルトです。

クローンは明らかなようです。

&$ objを使用して、$objが参照するオブジェクトへの参照ではなく$objへのエイリアスを作成します。php.netの引用:

$c = new A;
$d = &$c;
$c->foo = 2;
$c = NULL;
echo $d->foo."\n"; // Notice:  Trying to get property of non-object...
于 2012-07-19T15:24:47.947 に答える
2

myfunc($ obj)//識別子を渡す

関数がオブジェクトにアクセスし、何らかの方法でオブジェクトを操作/読み取る必要がある場合に使用します。

myfunc(&$ obj)//識別子への参照を渡します。

ここで重要なのは、識別子への参照を渡すことです。つまり、外部変数($ obj)がnullに設定されている場合、$ objから識別子を削除し、その識別子への参照も削除されているため、内部オブジェクトもnullになります。識別子を渡す場合とは異なり、実際に行うことは識別子のコピーを渡すため、$ objがnullに設定されている場合でも、関数内の値はオブジェクトを指します。

例:

var x = new Object();

var y = x //y and x both contain **different** identifiers to the same object in memory.

function a($_a){} // a function for examples

a($y) // passes in a copy of $y so $_a (inside the function) is a third identifier pointing to th in memory object

a(& $y) // now $_a contains the **same** identifier as $y so if either is emptied then the other is also emptied. 

a(clone $y) //creates a new object identical to the first and passes in an identifier of the new object.

それが十分に明確であることを願っています。

関数内から識別子を変更または削除し、独立して計算された値を返すことができる一方で、外部識別子変数に影響を与えることができるようにする場合は、参照によって識別子を渡します。たとえば、オブジェクトをシリアル化し、ファイルに保存してファイル文字列を返すだけでなく、オブジェクトをメモリからクリアできるように識別子をクリアします。

于 2012-07-19T15:31:44.640 に答える