zoukankan      html  css  js  c++  java
  • 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. }
  • 相关阅读:
    T-SQL常用的函数
    webservice和wcf和web.api简单介绍
    c#索引器
    在eclipse中使用maven构建spring cloud微服务
    maven项目报错maven-resources-plugin:2.7 or one of its dependencies could not be resolved
    使用maven创建工程报错Could not resolve archetype org.apache.maven.archetype
    eclipse配置maven
    最新省市区json数据
    ORA-01461: can bind a LONG value only for insert into a LONG column
    js验证强密码 大小写字母数字字符四选三 且大于8位
  • 原文地址:https://www.cnblogs.com/ghjbk/p/8037491.html
Copyright © 2011-2022 走看看