当前位置:编程学习 > 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.zzzyk.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); */ 
 
 
补充:Web开发 , php ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,