通過前面章節的描述,我們已經知道了php中變數的儲存方式--所有的變數都儲存在zval結構中。 下面介紹一下php核心如何實現變數的定義方式以及作用域。
在ze進行詞法和語法的分析之後,生成具體的opcode,這些opcode最終被execute函式(zend/zend_vm_execute.h:46)解釋執行。 在excute函式中,有以下**:
while (1)
}
...}
這裡的ex(opline)->handler(…)將op_array中的操作順序執行, 其中變數賦值操作在zend_assign_spec_cv_const_handler()函式中進行。 zend_assign_spec_cv_const_handler中進行一些變數型別的判斷並在記憶體中分配乙個zval,然後將變數的值儲存其中。 變數名和指向這個zval的指標,則會儲存於符號表內。 zend_assign_spec_cv_const_handler的最後會呼叫zend_vm_next_opcode()將op_array的指標移到下一條opline, 這樣就會形成迴圈執行的效果。
在ze執行的過程中,有四個全域性的變數,這些變數都是用於ze執行時所需資訊的儲存:
//_zend_compiler_globals 編譯時資訊,包括函式表等
zend_compiler_globals *compiler_globals;
//_zend_executor_globals 執行時資訊
zend_executor_globals *executor_globals;
//_php_core_globals 主要儲存php.ini內的資訊
php_core_globals *core_globals;
//_sapi_globals_struct sapi的資訊
sapi_globals_struct *sapi_globals;
在執行的過程中,變數名及指標主要儲存於_zend_executor_globals的符號表中,_zend_executor_globals的結構這樣的:
struct _zend_executor_globals
在執行的過程中,active_symbol_table會根據執行的具體語句不斷發生變化,針對執行緒安全的eg巨集就是用來取此變數中的值。 ze將op_array執行完畢以後,hashtable會被free_hashtable()釋放掉。 如果程式使用了unset語句來主動消毀變數,則會呼叫zend_unset_var_spec_cv_handler來將變數銷毀, **記憶體, 變數的生命週期
from 今天在論壇上看到有朋友發帖問道 既然靜態全域性變數與全域性變數都儲存在全域性資料區,為什麼作用域卻不一樣呢?也許答案非常簡單 c 就是這麼規定的,靜態全域性變數與全域性變數的唯一區別就是作用域不同。對乙個c 變數來說,有兩個屬性非常重要 作用域和生命週期,它們從兩個不同的維度描述了乙個變數...
變數的生命週期
1 全域性變數 作用域 全域性作用域 只需要在乙個原始檔中定義,就可以作用於所有的原始檔 生命週期 程式執行期一直存在 記憶體分布 全域性 靜態儲存區 注意 如果再兩個檔案中都定義了相同名字的全域性變數,則連線錯誤 變數重定義。2 全域性靜態變數 生命週期 程式執行期一直存在 作用域 檔案作用域 只...
switch case 變數生命週期
case 2 新增圖書 system.out.println n圖書資訊列表 system.out.print 請輸入新增圖書名稱 string name input.next 是否能新增圖書,如果貨架滿了 6 則無法新增false能新增true boolean flagadd false for ...