如果您發現引用計數的解釋令人困惑,Xdebug 擴充套件提供了一個類似於此函數的函數,但由於變數名稱是作為字串傳遞的,xdebug_debug_zval() 不會使用其自身對 zval 的引用來塗改引用計數。
(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)
debug_zval_dump — 傾印內部 zval 結構的字串表示到輸出
將內部 zval(Zend 值)結構的字串表示傾印到輸出。這主要用於理解或除錯 Zend 引擎或 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
如果不詳細了解引擎的實作方式,這個函式顯示的
refcount
值可能會令人感到意外。Zend 引擎使用引用計數有兩個不同的目的:
- 使用稱為「寫入時複製」(copy on write) 的技術來最佳化記憶體使用,其中多個持有相同值的變數指向記憶體中的同一個副本。當任何一個變數被修改時,它會指向記憶體中的一個新的副本,而原始副本的引用計數會減少 1。
- 追蹤已透過參考賦值或傳遞的變數(參見 參考說明)。此引用計數儲存在一個獨立的參考 zval 上,指向目前值的 zval。 debug_zval_dump() 目前不會顯示這個額外的 zval。
因為 debug_zval_dump() 將其輸入作為一般參數(以值傳遞),所以會使用寫入時複製技術來傳遞它們:並非複製資料,而是在函式呼叫的生命週期內將引用計數增加 1。如果函式在接收參數後修改了參數,則會建立一個副本;由於它沒有修改,因此它顯示的引用計數會比呼叫範圍中的引用計數多 1。
參數傳遞也阻止了 debug_zval_dump() 顯示已透過參考賦值的變數。為了說明這一點,請考慮上述範例的稍微修改版本:
<?php
$var1 = 'Hello';
$var1 .= ' World';
// 將三個變數設為指向相同值的參考
$var2 =& $var1;
$var3 =& $var1;
debug_zval_dump($var1);
?>上述範例會輸出
string(11) "Hello World" refcount(2)雖然 $var1、$var2 和 $var3 連結為參考,但只有「值」被傳遞給 debug_zval_dump()。該值在參考集合中使用一次,在 debug_zval_dump() 函式內部使用一次,因此顯示的引用計數為 2。
由於引擎針對不同資料類型進行了優化,因此會產生進一步的複雜性。某些類型,例如整數,不使用「寫入時複製」,因此根本不會顯示引用計數。在其他情況下,引用計數會顯示內部使用的額外副本,例如當字面字串或陣列儲存為程式碼指令的一部分時。
如果您發現引用計數的解釋令人困惑,Xdebug 擴充套件提供了一個類似於此函數的函數,但由於變數名稱是作為字串傳遞的,xdebug_debug_zval() 不會使用其自身對 zval 的引用來塗改引用計數。