This article through the PHP source code, starting from the structure of static variables, constants, magic constants analysis.
1. Static variablesAs we all know, static variables are loaded when the PHP script loads, That is 1. The object can be directly invoked without new, 2. and static variables stored in the common area of the same class of multiple objects to operate a static variable, 3. Static variables will only be released after the script is finished, and for these three questions, ask why.
below unfold the narrationFirst look at its structure, better analysis and understanding. Static variables are stored in the function structure _zend_execute_data, and in this structure, there are two key structures, Op_array and symbol_table 1.*symbol_table the various variables inside this class, each time a new object , will open up new environment space, see PHP kernel--talking about the PHP soul hashtble case Two, 2. The compiled opcode of the function is stored in the *op_array structure, which is the logic of the function, which is a common space logic each time a new object. Not to open up their own environmental space independently "is critical to achieve static root cause"
zend/zend_compiles.h 384 line, execute the environment structure body
struct _zend_execute_data {
struct _zend_op *opline;
Zend_function_state function_state;
Zend_op_array *op_array;//... The function compiles the execution logic, after compiles the opcode binary code, is called Op_array, the common one logic
zval *object;
HashTable *symbol_table;//... The symbolic table address of this function, each time new will open up a novel space "---------
struct _zend_execute_data *prev_execute_data;
Zval *old_error_reporting;
Zend_bool nested;
Zval **original_return_value;
Zend_class_entry *current_scope;
Zend_class_entry *current_called_scope;
Zval *current_this;
struct _ZEND_OP *fast_ret; /* Used by Fast_call/fast_ret (finally keyword) * *
call_slot *call_slots;
Call_slot *call;
};
zend/zend_compiles.h 261 lines, Op_array structure code
struct _zend_op_array {
/* Common elements *
/Zend_uchar type;
...
/* Static Variables Support * *
HashTable *static_variables;//294 line, static variable
...
}
Example:
T1 () {
$a +=1;
static $b +=1;
T1 ();
T1 ();
} Add oneself to call 3 times
Results $a are 1 each time, and $b = 1,2,3
The reason for this is as follows: three times the call function opens up the symbol table "3 copies" [T_3 Execute_data]---->[symbol_table_3] [t_2 execute_data]---->[symbol_table_2] [t_1 Execute_data]---->[symbol_table_1] *op_array->* static variable table "one copy"
Conclusion:The variables of the class are stored in *symbol_table, each of which has its scope, and each instantiation creates an environmental space (see the example in the second part of Hashtable), and the static variable, as shown in the code, is stored inside the Op_array, Op_array what , compile the generated opcode code, stored is the logic of the function, no matter how many new objects, this logic is public, and static variables are stored in this structure, so the same class of different objects can be common to a static variable, also explained at the PHP level, Why static variables are invoked directly without new. Explains problem one or two, because static variables are stored inside the Op_array, and Op_array are released after the execution of the script, so it's also released at this time. Explain question three.
2. ConstantFirst look at the difference between a constant and a variable, a constant that adds an extra element based on the ZVAL structure of the variable. As shown below is the internal structure of the constants in PHP.
Structure of constants (33 lines of zend/zend_constants.h file)
typedef struct _ZEND_CONSTANT {
zval value;/* zval structure, PHP internal variable storage structure
/char *name;/* Constant name/* UINT
NAME_LEN;
int flags; /* Constant tags such as const_persistent | Const_cs *
/int module_number; /* Module number *
/} zend_constant;
Structure such as, Name,name_len at a glance, it is worth mentioning that the Zval and variables stored in the same zval structure, (see the PHP kernel storage mechanism (separation/change)) mainly explained under flag and Module_number
1.flags:
C.flags = Case_sensitive/case insensitive; 1,0
Assignment to open case sensitivity for the structure field
2.module_number:
1.php_user_constant: User-defined constants
(The module numbers for the constants defined by the Define function are all)
2.register_main_long_constant:php Built-in definition constants
such as error reporting level E_all, E_warning,php_version constants, are persistent constants, the last to destroy
3. Magic ConstantsSay is a constant, in fact, each value in different positions, may be not the same, the reason is why. Instead of parsing at run time, the PHP kernel replaces the content assignment of these constants in lexical parsing. The following PHP code:
Taking __function__ as an example, in the Zend/zend_language_scanner.l file, __function__ is a meta tag (token) that needs to be parsed:
This is where, when the current intermediate code is in a function, the current function name is assigned to Zendlval (that is, the value content of the token T_func_c), and if not, the empty string is assigned to Zendlval (therefore printing directly in the top-level role domain name __function_ _ will output spaces). This value is directly assigned to the return value when parsing. So we see that the positions of these constants are already assigned in the generated intermediate code.
Just remember, the function that the top code implements, converts the __function__ to the corresponding value at the time of lexical analysis. (PHP has CG and eg two macros, respectively, to obtain Compile_global data and excutor_global data, respectively, they have their respective function_table and class_table,
In addition, require in PHP is performed as a function, so you need to know how to switch between eg and CG. )