2017-02-02 19 views
2

知っている人のための質問。 PHP documentation(php5の場合)は、オブジェクトを受け入れるメソッドの場合、実際に渡される値は「オブジェクトアクセサーが実際のオブジェクトを見つけることを可能にするオブジェクト識別子」であるため、 。問題は、あなたが実際にを実行したときに何が起こっているかということです。はこれを行いますか?PHPで、フードの下で参照によってオブジェクトを渡すとどうなりますか?

は、次のコードを考えてみましょう:

<?php 
function foo(&$arg){ 
    if(is_array($arg)){ 
     print $arg['foo']; 
    } 
    if(is_object($arg)){ 
     print $arg->{'foo'}; 
    } 
} 
$o1 = new \stdClass; 
$o1->foo = 'bar'; 
$a1 = ['foo'=>'bar']; 
print sprintf("O1 foo: %s", foo($o1)); 
print sprintf("a1 foo: %s", foo($a1)); 

これは正しく出力:

o1 foo: bar 
a1 foo: bar 

疑問は、なぜですか?実際のオブジェクトへのアクセスを許可するこのオブジェクト識別子参照で何が起きているのか誰でも説明できますか?

+0

「なぜ」。どうして? –

答えて

3

オブジェクトを保持する変数は、オブジェクトを直接保持していません。オブジェクトの識別子を保持します。オブジェクトプールに番号が付けられているオブジェクトプールのどこかに存在するオブジェクトとして想像してみましょう。 #5。すべての変数には"オブジェクト#5"が含まれています。 PHPは、変数がオブジェクトを参照しており、オブジェクト#5であると認識しています。

オブジェクト参照を保持するそのような変数を使用すると、PHPは参照されたオブジェクトをオブジェクトプールから検索します。

このような変数を関数に渡すと、PHP はその参照のコピーを作成します。内容を保持する2つの変数があります。"オブジェクト#5"。オブジェクト自体はコピーされておらず、"オブジェクト#5"という小さなメモです。

あなたが参照によって機能に、このような変数を渡す

は、よく、あなたは参照することにより、「オブジェクト#5」そのノートを渡しています。 PHPはそのコピーを作成しません。しかし、それはまだ"オブジェクト#5"と言っている変数なので、PHPを使って作業しようとすると、PHPはプールからオブジェクトを検索します。

このオブジェクト参照メカニズムは、&参照渡しメカニズムと同じではありません。オブジェクト参照メカニズムは、他のすべての値渡し操作とまったく同じように機能します。オブジェクトへの参照を表す値は、常に特定の方法(PHPは実際のオブジェクトを他の場所で調べなければならない)で扱われているということだけです。

+0

ありがとうございます。非常に徹底的に私の質問に答えた。 – Aron

+0

フォローアップ:私は上記のことから、オブジェクトをメソッド/関数に参照渡しするのは間違っていても、実際に何かを傷つけるわけではないことを前提としています。その声明は本当ですか? – Aron

+0

これは傷つけることはありません。*しかし、呼び出し元の変数への参照を保持していて**その値**を操作できるようになったので、変数を変更することでバグを導入しやすくなりました。それを期待する。 – deceze

関連する問題