当前位置:首页 > 服务端 > PHP内核研究 静态变量

PHP内核研究 静态变量

静态变量

它可以是 静态全局变量,如果不调用unset,那么这个静态变量会一直存在,直到程序退出时才由Zend内存管理来释放

它可以是 静态局部变量:在函数里定义,函数执行完后,该静态变量不会消失

它可以是 静态成员变量:在类里定义,它可以在所有类的对象中共享

例如

 

  1. <?php 
  2.   
  3. function test(){ 
  4.   
  5. static $a=1; 
  6.   
  7. $a++; 
  8.   
  9.   
  10. test(); //$a=2 
  11.   
  12. test();//$a=3 
  13.   
  14. test();//$a=4 

 

最后 $a=4了..

下面我们从内核里面分析它

static不是一个函数 ,它是一个关键字 ,所以只能从LEX语法分析中来查找

打开 zend/zend_language_scanner.l 查找 static

找到代码

 

  1. <ST_IN_SCRIPTING>"static" { 
  2.         return T_STATIC; 

 

是一个宏
再打开 zend/zend_language_pareser.l
搜 T_STATIC
找到代码

 

  1. T_STATIC static_var_list ';' 

跟进 static_var_list
找到代码

 

  1. static_var_list: 
  2.                 static_var_list ',' T_VARIABLE { zend_do_fetch_static_variable(&$3, NULL, ZEND_FETCH_STATIC TSRMLS_CC); } 
  3.         |       static_var_list ',' T_VARIABLE '=' static_scalar { zend_do_fetch_static_variable(&$3, &$5, ZEND_FETCH_STATIC TSRMLS_CC); } 
  4.         |       T_VARIABLE  { zend_do_fetch_static_variable(&$1, NULL, ZEND_FETCH_STATIC TSRMLS_CC); } 
  5.         |       T_VARIABLE '=' static_scalar { zend_do_fetch_static_variable(&$1, &$3, ZEND_FETCH_STATIC TSRMLS_CC); } 
  6.   

就是这里了..它由PHP的语法分析程序 解析成上面的代码
zend_do_fetch_static_variable 这个函数就是了
它在zend/zend_compile.c里定义
代码如下

 

    1. void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) 
    2.         zval *tmp;  //一个临时变量 
    3.         zend_op *opline; 
    4.         znode lval; 
    5.         znode result; 
    6.   
    7.         ALLOC_ZVAL(tmp); //申请一块内存 
    8.   
    9.         if (static_assignment) { 
    10.                 *tmp = static_assignment->u.constant; 
    11.         } else { 
    12.                 INIT_ZVAL(*tmp); 
    13.         } 
    14.         if (!CG(active_op_array)->static_variables) {//初始化静态变量的HASH 键值 
    15.                 ALLOC_HASHTABLE(CG(active_op_array)->static_variables); 
    16.                  //初始化HASH值 
    17.                 zend_hash_init(CG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0); 
    18.         } 
    19.         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); 
    20.   
    21.         if (varname->op_type == IS_CONST) { 
    22.                 if (Z_TYPE(varname->u.constant) != IS_STRING) { 
    23.                         convert_to_string(&varname->u.constant); 
    24.                 } 
    25.         } 
    26.   
    27.         opline = get_next_op(CG(active_op_array) TSRMLS_CC); 
    28.         opline->result.op_type = IS_VAR; 
    29.         opline->result.u.EA.type = 0; 
    30.         opline->result.u.var = get_temporary_variable(CG(active_op_array)); 
    31.         opline->op1 = *varname; 
    32.         SET_UNUSED(opline->op2); 
    33.         opline->op2.u.EA.type = ZEND_FETCH_STATIC; 
    34.         result = opline->result; 
    35.   
    36.         if (varname->op_type == IS_CONST) { 
    37.                 zval_copy_ctor(&varname->u.constant); 
    38.         } 
    39.         fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */ 
    40.   
    41.         if (fetch_type == ZEND_FETCH_LEXICAL) { 
    42.                 znode dummy; 
    43.   
    44.                 zend_do_begin_variable_parse(TSRMLS_C); 
    45.                 zend_do_assign(&dummy, &lval, &result TSRMLS_CC); 
    46.                 zend_do_free(&dummy TSRMLS_CC); 
    47.         } else { 
    48.                 zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC); 
    49.         } 
    50.         CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED; 
    51.   
    52. /*      zval_dtor(&varname->u.constant); */ 
    53. }

作者:ノGHJ
来源链接:https://www.cnblogs.com/ghjbk/p/8037491.html

版权声明:
1、Java侠(https://www.javaxia.com)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaxia.com/server/124827.html

标签: unused variable
分享给朋友:

“PHP内核研究 静态变量” 的相关文章