17

次のコードを考えてみましょう。

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」を割り当てた後:
Hello

obj1: (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->var1haveがあるのですか?refcount=2

newオペレーターが割り当てを行う方法のためですか?PHP は参照を使用して代入を行います。でインスタンス化するとnew、シンボル/変数名はそのインスタンスに関連付けられません。ただし、クラス プロパティには名前があります。これのrecount=2せいでしょうか?

その場合は、クラス インスタンスの浅いコピー WRT で COW (コピー オン ライト) が発生しています。プロパティは、 を使用してインスタンス化中に作成されたプロパティの zval をまだ指していますnew

今、

$obj->var1 に「Hello」を割り当てた後:
Hello

obj1: (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が使用されたときにメモリ割り当てがどのように行われるかを調べようとしています。でも、今しなければならないことは他にもたくさんあります。すぐに有益なアップデートを投稿できることを願っています。それまでは、私が見ていたコードへのリンクを次に示します。

4

2 に答える 2

4

別のインスタンス化を追加する$obj2 = new a;と、refcountが4ではなく3に増加するため、xdebug_debug_zvalを呼び出した結果として発生します。xdebug関数の目的は、変数を関数に渡し、(場合によっては)追加の参照を作成することによる混乱を回避することです。

残念ながら、これはメンバー変数には適用されません。それらをエクスポートするために、それらのzvalへの別の参照が作成されます。したがって、debug_zval_dumpのドキュメントの注記に記載されているすべての警告と紛らわしい状況は、引き続きメンバー変数に適用されます。

于 2011-12-29T16:54:58.803 に答える
2

次のページの「注意: refcount に注意してください」セクションでこれについて説明していると思います: http://php.net/manual/en/function.debug-zval-dump.php

zend が渡される方法を最適化すると参照カウントが増加することを示していますが、「警告」はコピーオンライトが呼び出されたときにあり、参照カウントを 1 に戻します。

それが役立つことを願っています

于 2011-12-29T17:04:11.690 に答える