debug_zval_dump
(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)
debug_zval_dump — 内部的な zval を表す文字列をダンプする
説明
内部的な zval (Zend の値) を表す文字列表現をダンプします。 これは Zend Engine や PHP 拡張モジュールの実装の詳細をデバッグしたり、理解したりするのに役立ちます。
パラメータ
value
-
ダンプする変数または値。
values
-
ダンプする追加の変数または値。
戻り値
値を返しません。
例
例1 debug_zval_dump() の例
<?php
$var1 = 'Hello';
$var1 .= ' World';
$var2 = $var1;
debug_zval_dump($var1);
?>
上の例の出力は以下となります。
string(11) "Hello World" refcount(3)
注意:
refcount
を理解する
Zend Engine の実装の詳細を理解していないと、 この関数が表示する
refcount
の値に驚くかもしれません。Zend Engine は、リファレンスカウントを以下の2つの用途で使います:
- "コピーオンライト" と呼ばれるテクニックを使ってメモリを最適化し、 値が同じ複数の値を保持する複数の変数を、メモリ上の同じコピーを指すようにします。 この場合、変数の値が変更された時に、 その変数は新しいメモリ上のコピーの値を指すようになります。 そして、その変数のリファレンスカウントは1になります。
- リファレンス渡しされたり、リファレンスが代入されている値( リファレンスの説明 も参照ください) を追跡する用途にも使います。 この用途のリファレンスカウントは、 現在の値を指しているものとは別の、リファレンス用の zval に保存されています。 この追加の zval は、現状 debug_zval_dump() では見えません。
debug_zval_dump() は、値渡しされた通常の引数を入力として受け取るので、 コピーオンライトのテクニックを使います: つまり、データをコピーせず、 関数呼び出しが行われている間、リファレンスカウントをひとつ増やします。 関数が受け取った引数を変更すると、データのコピーが行われます。 コピーを行わないと、呼び出しスコープの中でリファレンスカウントがひとつ増えてしまうからです。
渡す引数によっては、debug_zval_dump() はリファレンスが割り当てられている変数を表示しません。 この動きを示すために、上の例をちょっと変更した例を考えてみましょう:
<?php
$var1 = 'Hello';
$var1 .= ' World';
// Point three variables as references to the same value
$var2 =& $var1;
$var3 =& $var1;
debug_zval_dump($var1);
?>上の例の出力は以下となります。
string(11) "Hello World" refcount(2)$var1, $var2, $var3 はリファレンスで結びついていますが、 値 だけが debug_zval_dump() に渡されます。 この値は、リファレンスの設定に一度使われ、 debug_zval_dump() の中で一度使われます。 よって、リファレンスカウントは2になります。
データ型によっては、Zend Engine 内で最適化が行われてしまうため、 ユーザはさらに混乱してしまいます。 整数のように "コピーオンライト" を行わないデータ型の変数では、 リファレンスカウントを全く表示しません。 別の場合、このリファレンスカウントの値は、 内部的に使われる追加のコピーの値を表示する場合もあります。 たとえば、文字列リテラルや配列が、命令セットの一部として保存されているような場合です。
参考
- var_dump() - 変数に関する情報をダンプする
- debug_backtrace() - バックトレースを生成する
- リファレンスの説明
- » References Explained (by Derick Rethans)
User Contributed Notes 1 note
If you're finding the interpretation of refcount confusing, the Xdebug extension offers a function similar to this one, but because the variable name is passed as a string, xdebug_debug_zval() doesn't scribble on the refcount with its own references to the zval.