程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP內核研究 靜態變量

PHP內核研究 靜態變量

編輯:關於PHP編程

靜態變量 它可以是 靜態全局變量,如果不調用unset,那麼這個靜態變量會一直存在,直到程序退出時才由Zend內存管理來釋放   它可以是 靜態局部變量:在函數裡定義,函數執行完後,該靜態變量不會消失   它可以是 靜態成員變量:在類裡定義,它可以在所有類的對象中共享   例如       <?php     function test(){     static $a=1;     $a++;     }     test(); //$a=2     test();//$a=3     test();//$a=4    最後 $a=4了..   下面我們從內核裡面分析它   static不是一個函數 ,它是一個關鍵字 ,所以只能從LEX語法分析中來查找   打開 zend/zend_language_scanner.l 查找 static   找到代碼       <ST_IN_SCRIPTING>"static" {          return T_STATIC;  }    是一個宏 再打開 zend/zend_language_pareser.l 搜 T_STATIC 找到代碼   T_STATIC static_var_list ';'  跟進 static_var_list 找到代碼   static_var_list:                  static_var_list ',' T_VARIABLE { zend_do_fetch_static_variable(&$3, NULL, ZEND_FETCH_STATIC TSRMLS_CC); }          |       static_var_list ',' T_VARIABLE '=' static_scalar { zend_do_fetch_static_variable(&$3, &$5, ZEND_FETCH_STATIC TSRMLS_CC); }          |       T_VARIABLE  { zend_do_fetch_static_variable(&$1, NULL, ZEND_FETCH_STATIC TSRMLS_CC); }          |       T_VARIABLE '=' static_scalar { zend_do_fetch_static_variable(&$1, &$3, ZEND_FETCH_STATIC TSRMLS_CC); }     ;  就是這裡了..它由PHP的語法分析程序 解析成上面的代碼 zend_do_fetch_static_variable 這個函數就是了 它在zend/zend_compile.c裡定義 代碼如下   void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC)  {          zval *tmp;  //一個臨時變量          zend_op *opline;          znode lval;          znode result;             ALLOC_ZVAL(tmp); //申請一塊內存             if (static_assignment) {                  *tmp = static_assignment->u.constant;          } else {                  INIT_ZVAL(*tmp);          }          if (!CG(active_op_array)->static_variables) {//初始化靜態變量的HASH 鍵值                  ALLOC_HASHTABLE(CG(active_op_array)->static_variables);                   //初始化HASH值                  zend_hash_init(CG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);          }          zend_hash_update(CG(active_op_array)->static_variables, varname->u.constant.value.str.val, varname->u.constant.value.str.len+1, &tmp, sizeof(zval *), NULL);             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->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 = ZEND_FETCH_STATIC;          result = opline->result;             if (varname->op_type == IS_CONST) {                  zval_copy_ctor(&varname->u.constant);          }          fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */  www.2cto.com            if (fetch_type == ZEND_FETCH_LEXICAL) {                  znode dummy;                     zend_do_begin_variable_parse(TSRMLS_C);                  zend_do_assign(&dummy, &lval, &result TSRMLS_CC);                  zend_do_free(&dummy TSRMLS_CC);          } else {                  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;     /*      zval_dtor(&varname->u.constant); */  }     

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved