8
  $var = 1;
  debug_zval_dump($var);

出力:

long(1) refcount(2)


  $var = 1;
  $var_dup = &$var;
  debug_zval_dump($var);exit;

出力:

long(1) refcount(1)

アップデート

回答に非常にがっかりしました...

4

5 に答える 5

29

void debug_zval_dump (混合$変数);


コード:

$var = 1;              # $var's Refcount = 1
debug_zval_dump($var); # $var is passed by refrence intarlly.

出力:

long(1) refcount(2)

説明: $var の refcount が 1 であるため、PHP はこれを最適化し、他の参照を汚染する可能性がないため、コピーを作成する代わりにメモリを直接処理します。PHP は、必要に応じてメモリを直接編集できるように、参照によって $var を内部的に渡します。2 番目の参照は、実際に debug_zval_dump() を呼び出すときに作成されます。

ここで、refcount が 2 であることは、非常に明白ではありません。それで、何が起こっているのですか?

変数が単一の参照を持つ場合 (debug_zval_dump() への引数として使用される前に $var がそうであったように)、PHP のエンジンはそれが関数に渡される方法を最適化します。内部的には、PHP は $var を参照のように扱います (この関数のスコープに対して refcount が増加するという点で)。ただし、渡された参照がたまたま書き込まれた場合、コピーが作成されますが、書き込みの時点でのみ行われます。 . これは「コピーオンライト」として知られています。

そのため、debug_zval_dump() がたまたまその唯一のパラメーターに書き込みを行った場合 (書き込みを行わない場合)、コピーが作成されます。それまでは、パラメーターは参照のままであり、関数呼び出しのスコープに対して refcount が 2 にインクリメントされます。


コード:

$var = 1;              # $var's Refcount = 1
$var_dup = &$var;      # $var's Refcount = 2
debug_zval_dump($var); # A copy is passed as $var's refcount is 2.

出力:

long(1) refcount(1)

説明: 今回は、関数が呼び出されたときに $var のコピーが作成されています。これは、$var が 2 回参照されており、PHP が他の参照を汚染したくないため、自分自身が作業できるように $var のコピーを作成するためです。関数呼び出しのスコープにのみ使用される別のメモリがあるため、参照は 1 つだけで、それは自己です。したがって、関数のスコープでは、コピーの refcount は 1 (それ自体) です。

于 2010-11-19T02:41:26.273 に答える
7

このメソッドのドキュメントでは、「参照カウントに注意する」セクションでこれを説明していると思います。

debug_zval_dump

于 2011-04-22T13:55:16.390 に答える
2

コード:

$var = 1;
debug_zval_dump($var);

出力:long(1) refcount(2)

説明: debug_zval_dump() の引数として使用される前の $var のように、変数が 1 つの参照を持つ場合、PHP のエンジンはそれが関数に渡される方法を最適化します。PHP は、基本的に変数へのポインターを作成し、内部的には、PHP は $var を参照のように扱うため、この関数のスコープに対して refcount が増加します。

コード:

$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;

出力:long(1) refcount(1)

説明: ここで、$var 変数は書き込み時にコピーされ、その変数のまったく新しい別のインスタンスが作成されます。debug_zval_dump は、参照ではなく、$var のまったく新しいコピーを扱っているため、refcount は 1 です。機能が実行されます。

それが解決することを願っています。

于 2011-04-25T08:41:57.360 に答える
1

debug_zval_dump()関数と変数の処理方法をもう少し詳しく説明します。私が間違っていても殺さないでください:)...

  $var = 1;
  debug_zval_dump($var);

1 は の値であるため、デバッグ関数は$varrefcount(1) と 1 refcount(2) をカウントすると思います$var
論理的に見れば、あなたは実際にこれを言っているのです。

  1 = 1;
  debug_zval_dump(1);

第二部:

$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;

ここに表示されるのは、設定$var$var_dupたものの、その値を保持していることです。$varに「リンク」したため、 の参照カウントは 1 です$var_dup

$var = 2;
$var_dup = &$var; //or $var = &$var_dup; (doesn't matter which one)
$var = 3;
debug_zval_dump($var_dup);exit;

これによりlong(3) refcount(1)...なぜrefcount 1なのか? $var_dup の値が 3 に割り当てられていないことがわかるように、2 になるはずですよね? &$var で最新の状態に保つ必要はありません。これは、と の$var = 4間を通過すると、それらをリンクしたため $var_dup の値が自動的に更新され、1 refcount になることを意味します。$var = 3debug_zval_dump($var_dup);exit;

次に、この別の出来事があります:

$var = 2;
$var_dup = $var;
$var = 4;
debug_zval_dump($var_dup);exit;

これの出力は次のとおりlong(2) refcount(2)です。ご覧のとおり、$var_dup の値は正しいです。$var は 2 で、値は $var_dup を介して渡され、彼はそれに固執しました。$var = 4;はとをカウントするため、refcount は 2 です$var_dup = $var;。を削除すると、次の$var = 4;ようになります。

$var = 2;
$var_dup = $var;
debug_zval_dump($var_dup);exit;

これの出力は次のとおりlong(2) refcount(3)です。現在、デバッグ関数は以下をカウントします: $var_dup(1)、=$var(2) ($var_dup は $var から生成されたため)、$var( = 2;)(3)。

私の言いたいことを理解していただければ幸いです。私の意見では、これはプログラミングよりも数学に近いため、理解するのが難しい関数である理由かもしれません.

繰り返しますが、もし私が間違っていたとしても、私を殺さないでください :)...こんにちは

ミクシフォイド

免責事項
この関数の目的がわかりません。実は今日まで聞いたことがありませんでした。したがって、不適切な使用については責任を負いません:)。

于 2011-04-19T17:22:20.270 に答える
1

ここで、refcount が 2 であることは、非常に明白ではありません。特に上記の例を考えると。それで、何が起こっているのですか?

変数が単一の参照を持つ場合 (debug_zval_dump() の引数として使用される前の $var1 のように)、PHP のエンジンはそれが関数に渡される方法を最適化します。内部的には、PHP は $var1 を参照のように扱います (この関数のスコープの refcount が増加するという点で)。ただし、渡された参照がたまたま書き込まれた場合、コピーが作成されますが、書き込みの時点でのみ行われます。 . これは「コピーオンライト」として知られています。

そのため、debug_zval_dump() がたまたまその唯一のパラメーターに書き込みを行った場合 (書き込みを行わない場合)、コピーが作成されます。それまでは、パラメーターは参照のままであり、関数呼び出しのスコープに対して refcount が 2 にインクリメントされます。

-- クレジットは php マニュアルに移動します。関数に付属する説明全体を読んでください。

---編集:おっと、答える前にもっとコメントを読むべきです:Dとにかく、これは前に述べた質問への答えです。

于 2011-04-19T18:02:52.033 に答える