Home  >  Article  >  Backend Development  >  PHP Kernel Research Static Variables_PHP Tutorial

PHP Kernel Research Static Variables_PHP Tutorial

WBOY
WBOYOriginal
2016-07-14 10:08:23945browse

static variable

It can be a static global variable. If unset is not called, then this static variable will always exist and will be released by Zend memory management until the program exits
It can be a static local variable: defined in a function, the static variable will not disappear after the function is executed
It can be a static member variable: defined in a class, it can be shared among objects of all classes
For example
function test(){
static $a=1;
$a++;
}
test(); //$a=2
test();//$a=3
test();//$a=4
Finally $a=4..
Let’s analyze it from the kernel
static is not a function, it is a keyword, so it can only be found from LEX syntax analysis
Open zend/zend_language_scanner.l and find static
Code found
"static" {
return T_STATIC;
}
is a macro
Open zend/zend_language_pareser.l
Search T_STATIC
Code found
T_STATIC static_var_list ';'
Follow up static_var_list
Code found
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); }
;
That’s it.. It is parsed into the above code by PHP’s syntax parser
zend_do_fetch_static_variable is the function
It is defined in zend/zend_compile.c
The code is as follows
void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC)
{
zval *tmp; //A temporary variable
zend_op *opline;
znode lval;
znode result;
ALLOC_ZVAL(tmp); //Apply for a piece of memory
if (static_assignment) {
*tmp = static_assignment->u.constant;
} else {
INIT_ZVAL(*tmp);
} }
if (!CG(active_op_array)->static_variables) {//Initialize the HASH key value of static variables
ALLOC_HASHTABLE(CG(active_op_array)->static_variables);
                                    // Initialize HASH value                                                    
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); */ 
 
 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/477784.htmlTechArticle静态变量 它可以是 静态全局变量,如果不调用unset,那么这个静态变量会一直存在,直到程序退出时才由Zend内存管理来释放 它可以是 静态局部...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn