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
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); */
}
http://www.bkjia.com/PHPjc/477784.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/477784.htmlTechArticle静态变量 它可以是 静态全局变量,如果不调用unset,那么这个静态变量会一直存在,直到程序退出时才由Zend内存管理来释放 它可以是 静态局部...