我想讓xdebug有一天能夠瀏覽所有的靜態變量和屬性,但根據作者,無法在引擎中獲取這些列表。這對我來說很令人驚訝,因爲靜態看起來像是具有孤立範圍的全局變量。PHP靜態變量是如何在內部實現的?
它們真的沒有存儲在散列表中,還是表項無法枚舉的問題?
我想讓xdebug有一天能夠瀏覽所有的靜態變量和屬性,但根據作者,無法在引擎中獲取這些列表。這對我來說很令人驚訝,因爲靜態看起來像是具有孤立範圍的全局變量。PHP靜態變量是如何在內部實現的?
它們真的沒有存儲在散列表中,還是表項無法枚舉的問題?
PHP函數可以在內部有兩種:內部函數或用戶定義的函數。內部函數用C編寫,可以做任何事情。用戶定義的函數由其元數據的「oparray」表示。 oparray包含PHP/ZE字節碼形式的函數表達式。 oparray的一個元素包含所有靜態變量的表格。
因此,爲了獲得所有靜態變量,必須迭代所有用戶定義的函數(以及所有類中的類方法)並檢查該數組。
對於全局函數這個未經測試的C代碼可能做的伎倆:
int dump_statics(zend_function *function TSRMLS_DC)
{
if (function->type == ZEND_USER_FUNCTION) {
ulong hashIndex = 0;
char* hashKey = NULL;
int hashKeyType = 0;
zend_hash_internal_pointer_reset(function->op_array.static_variables);
while ((hashKeyType = zend_hash_get_current_key(function->op_array.static_variables, &hashKey, &hashIndex, 0)) {
if (hashKeyType == HASH_KEY_IS_STRING) {
php_printf("%s\n", hashkey);
}
zend_hash_move_forward(function->op_array.static_variables);
}
}
return 0;
}
zend_hash_apply(EG(function_table), (apply_func_t) dump_statics TSRMLS_CC);
對於類方法必須遍歷EG(class_table),然後類條目的包括funtion_table ......被留下作爲讀者的練習。 (如測試上面的代碼)
更新:
我創建了一個簡單的PHP擴展這樣做。它可以從https://github.com/johannes/php-staticvardumper
我假設你的意思是「所以爲了得到所有靜態*變量*必須迭代...」 –
@SteveClay謝謝,修正 – johannes
所以我假設'hashKey'引用某種全局可訪問的表?而xdebug,保持快速,可能需要所有這些哈希鍵在一個大的鏈表中?只是好奇:全局存儲在同一個表中? –
我敢肯定你最好問Derick Rethans(XDebug的作者和PHP語言/ Zend Engine的活躍開發人員),或者在php內部列表中詢問這個問題([email protected] .net) – Tularis
我認爲,把它們視爲全球變量是一個狹隘的觀點。你可以在一個函數中有一個靜態變量,它只會被初始化一次。否則就像其他變量一樣。 –
@BrentBaisley請注意,除了允許使用快捷鍵初始值設定項的靜態參數外,它們的表現完全相同:http://3v4l.org/68uRA –