2014-02-17 34 views
0

我想讓xdebug有一天能夠瀏覽所有的靜態變量和屬性,但根據作者,無法在引擎中獲取這些列表。這對我來說很令人驚訝,因爲靜態看起來像是具有孤立範圍的全局變量。PHP靜態變量是如何在內部實現的?

它們真的沒有存儲在散列表中,還是表項無法枚舉的問題?

+0

我敢肯定你最好問Derick Rethans(XDebug的作者和PHP語言/ Zend Engine的活躍開發人員),或者在php內部列表中詢問這個問題([email protected] .net) – Tularis

+0

我認爲,把它們視爲全球變量是一個狹隘的觀點。你可以在一個函數中有一個靜態變量,它只會被初始化一次。否則就像其他變量一樣。 –

+0

@BrentBaisley請注意,除了允許使用快捷鍵初始值設定項的靜態參數外,它們的表現完全相同:http://3v4l.org/68uRA –

回答

2

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

+0

我假設你的意思是「所以爲了得到所有靜態*變量*必須迭代...」 –

+0

@SteveClay謝謝,修正 – johannes

+0

所以我假設'hashKey'引用某種全局可訪問的表?而xdebug,保持快速,可能需要所有這些哈希鍵在一個大的鏈表中?只是好奇:全局存儲在同一個表中? –