原:PHP核心功能研究之 global

來源:互聯網
上載者:User
聲明:本文為斯人原創,全部為作者一一分析得之,有不對的地方望賜教。
歡迎轉載,轉載請註明出處 。

本文地址:http://imsiren.com/archives/601

好久沒有寫部落格了…最近事挺多,
換了工作,又搬了家..
今天就來說說 我們經常用到的global語句吧..
我們都知道,在函數體內聲明的變數,範圍只是當前函數體中,一般情況下是訪問不到外部聲明的變數的.
因為全域變數和局部變數存放在不同的hashTable,
全域變數在symbol_table中,而局部變數則存在active_symbol_table中.
這樣就將它們分開了,那 global是怎麼實現的呢?
經過簡單分析,通過RE2C&&YACC定位到 global的token

T_GLOBAL global_var_list ';'................global_var_list:                global_var_list ',' global_var  { zend_do_fetch_global_variable(&$3, NULL, ZEND_FETCH_GLOBAL_LOCK TSRMLS_CC); }        |       global_var                                              { zend_do_fetch_global_variable(&$1, NULL, ZEND_FETCH_GLOBAL_LOCK TSRMLS_CC); };

重點是在zend_do_fetch_global_variable這個函數中,我們進去看看,

void zend_do_fetch_global_variable(znode * varname,const znode * static_assignment,int    fetch_type TSRMLS_DC) /* {{{ */ {    zend_op * opline;    znode lval;    znode result;    if(varname->op_type == IS_CONST) {        if(Z_TYPE(varname->u . constant) != IS_STRING) {            convert_to_string(&varname->u . constant);        }    }    opline = get_next_op(CG(active_op_array)TSRMLS_CC);    opline->opcode = ZEND_FETCH_W;     /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */    opline->result . op_type = IS_VAR;    opline->result . u . EA . type = 0;    opline->result . u . var = get_temporary_variable(CG(active_op_array));    opline->op1 = * varname;    SET_UNUSED(opline->op2);    opline->op2 . u . EA . type = fetch_type;    result = opline->result;    if(varname->op_type == IS_CONST) {        zval_copy_ctor(&varname->u . constant);    }    fetch_simple_variable(&lval,varname,0TSRMLS_CC);     /* Relies on the fact that the default fetch is BP_VAR_W */    zend_do_assign_ref(NULL,&lval,&result TSRMLS_CC);    CG(active_op_array)->opcodes[CG(active_op_array)->last - 1] . result . u . EA . type |=        EXT_TYPE_UNUSED;}

1:此函數先驗證我們擷取的變數是否是常量,如果是常量並且不是字串類型,則就將它轉換成string類型.
2:此函數產生一個Op , ZEND_FETCH_W
3:釋放CONST
4:fetch_simple_variable會檢測是不是auto_global
最重要的地方是 ZEND_FETCH_W
通過計算 可以知道 op的函數是ZEND_FETCH_W_SPEC_CV_HANDLER

static int ZEND_FASTCALL  ZEND_FETCH_W_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS){        return zend_fetch_var_address_helper_SPEC_CV(BP_VAR_W, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);}

zend_fetch_var_address_helper_SPEC_CV的工作:
1:轉換成IS_STRING類型
2:如果是類的靜態成員,則通過::擷取過來,否則,通過zend_get_target_symbol_table函數返回全域變數symbol_table .
return &EG(symbol_table);
3:通過zend_hash_find 在 target_symbol_table 中尋找,target_symbol_table是一個臨時HashTable.用來存放 symbol_table的資料.
4: 如果沒有找到,則會以寫的方式 建立一條資料到target_symbol_table中.這就是,我們為什麼通過global一個不存在的變數的時候不出錯,並且會建立該變數的原因.

原文出處:http://imsiren.com/archives/601

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.