次のコードを考えてみましょう。
class a {
public $var1;
function disp(){
echo $this->var1;
}
}
$obj1 = new a;
echo '<br/>After instantiation into $obj1:<br/>';
xdebug_debug_zval('obj1');
$obj1->var1 = "Hello ";
echo '<br/><br/>After assigning "Hello" to $obj->var1:<br/>';
$obj1->disp();
echo "<br/><br/>";
xdebug_debug_zval('obj1');
出力:
$obj1 へのインスタンス化後:
obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=2, is_ref=0)=NULL }$obj->var1 に「Hello」を割り当てた後:
Helloobj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=1, is_ref=0)='Hello ' }
一つずつ:
$obj1 へのインスタンス化後:
obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=2, is_ref=0)=NULL }
クラス a のオブジェクトが 1 つしかないのに、なぜ$obj1->var1
haveがあるのですか?refcount=2
new
オペレーターが割り当てを行う方法のためですか?PHP は参照を使用して代入を行います。でインスタンス化するとnew
、シンボル/変数名はそのインスタンスに関連付けられません。ただし、クラス プロパティには名前があります。これのrecount=2
せいでしょうか?
その場合は、クラス インスタンスの浅いコピー WRT で COW (コピー オン ライト) が発生しています。プロパティは、 を使用してインスタンス化中に作成されたプロパティの zval をまだ指していますnew
。
今、
$obj->var1 に「Hello」を割り当てた後:
Helloobj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=1, is_ref=0)='Hello ' }
そのため、プロパティに値を割り当てると、そのプロパティ$obj1->var1
の新しい zval コンテナ、したがってrefcount=1
?
これは、インスタンス化中に作成された zval コンテナがnew
まだ生きているが、シンボル/変数名が関連付けられていないためアクセスできないことを意味しますか?
注意してください ( xdebug: Variable Display Featuresより):
debug_zval_dump()
は とは異なりxdebug_debug_zval()
ます。
void xdebug_debug_zval( [文字列変数名 [, ...]] )
変数に関する情報を表示します。
この関数は、型、値、および参照カウント情報を含む、1 つ以上の変数に関する構造化された情報を表示します。配列は、値を使用して再帰的に探索されます。この関数は、変数自体が実際に関数に渡されるために、PHP の debug_zval_dump() 関数が持つ問題を回避するために、PHP のdebug_zval_dump()関数とは異なる方法で実装されています。Xdebug のバージョンは、変数名を使用して内部シンボル テーブル内の変数を検索し、関数に変数を実際に渡す必要なく、すべてのプロパティに直接アクセスするため、より優れています。その結果、この関数が返す情報は、zval 情報を表示するための PHP 独自の関数よりもはるかに正確です。
UPDATE
:Dec 31th 2011:
newが使用されたときにメモリ割り当てがどのように行われるかを調べようとしています。でも、今しなければならないことは他にもたくさんあります。すぐに有益なアップデートを投稿できることを願っています。それまでは、私が見ていたコードへのリンクを次に示します。