PHP kernel (7) variables and data types-constants
Link: http://www.orlion.ga/246/
In PHP, the constant name is a simple value identifier, which cannot be changed during script execution. Like variables, constants are case-sensitive by default, but usually uppercase.
A constant adds an additional element based on the zval structure of the variable. The following shows the internal structure of constants in PHP.
1. Internal Structure of constants
Typedef struct _ zend_constant {zval value;/* zval structure, storage structure of PHP internal variables, which is described in the first section */int flags; /* constant tags such as CONST_PERSISTENT | CONST_CS */char * name;/* constant name */uint name_len; int module_number;/* module number */} zend_constant;
In the Zend/zend_constants.h file, you can see the structure definition shown above. In the constant structure, in addition to the same zval structure as the variable, it also includes the mark of the constant, the constant name, and the module number of the constant.
Let's look at the definition process of PHP constants:
define('TIPI', 'Thinking In PHP Internal');
This is a very common constant definition process. It uses the PHP built-in function difine () and the constant name is TIPI. The value is a string and is stored in the zval structure. Starting from this example, let's take a look at the implementation of the process in which define defines constants.
Ii. define the process of defining Constants
Define is a built-in function of PHP, which is defined in the Zend/zend_builtin_functions.c file. Some source code is as follows:
/* {Proto bool define (string constant_name, mixed value, boolean case_insensitive = false) Define a new constant */ZEND_FUNCTION (define) {if (distinct (ZEND_NUM_ARGS () TSRMLS_CC, "sz | B", & name, & name_len, & val, & non_cs) = FAILURE) {return ;}... // class constant definition this is not introduced... // judge and process the value type c. value = * val; zval_copy_ctor (& c. value); if (val_free) {zval_ptr_dtor (& val_free);} c. flags = case_sensitive;/* non persistent */c. name = zend_strndup (name, name_len); c. name_len = name_len + 1; c. module_number = PHP_USER_CONSTANT; if (zend_register_constant (& c TSRMLS_CC) = SUCCESS) {RETURN_TRUE;} else {RETURN_FALSE ;}}/*}}}*/
The code above has simplified the processing of objects and class constants. The implementation basically refers to passing the passed parameters to the newly created zend_constant structure, and register the struct to the constant list. The third parameter of the function is case insensitive. The default value is false (case sensitive ). This parameter is assigned to the flags field of the zend_constant struct. The Code implemented in the function is as follows:
Zend_bool non_cs = 0; // The temporary storage variable int case_sensitive = CONST_CS for the third parameter; // whether it is case sensitive. The default value is 1 if (non_cs) {// The input is true, case Insensitive case_sensitive = 0;} c. flags = case_sensitive; // assign a value to the struct Field
From the implementation of the preceding define function, PHP has no restrictions on the definition of constant names.
Iii. defined determine whether a constant is set
Like define, the implementation of defined is also in the Zend/zend_builtin_functions.c file. In fact, a process of reading the parameter variable, calling the zend_get_constant_ex function to obtain the constant value to determine whether the constant exists. The zend_get_constant_ex function includes not only regular constant acquisition, but also class constant acquisition. Finally, it obtains the constant value through the zend_get_constant function. In the zend_get_constant function, the constant value is basically obtained through the following code:
zend_hash_find(EG(zend_constants), name, name_len+1, (void **) &c)
In addition, the name can be processed only before and after the function is called.
Iv. Initialization of standard Constants
The module numbers of the constants defined by define are all PHP_USER_CONSTANT, indicating that this is a user-defined constant. In addition, we usually use more constants, such as the E_ALL constants used to display error reports of all levels. The cgi mode is used as an example to describe the definition process of a standard constant. The entire call sequence: php_cgi_startup ()-> php_module_startup ()-> zend_startup ()-> zend_register_standard_constant ()
Void evaluate (TSRMLS_D) {... // If the constant is REGISTER_MAIN_LONG_CONSTANT, set REGISTER_MAIN_LONG_CONSTANT ("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS );...}
REGISTER_MAIN_LONG_CONSTANT macro is implemented by zend_register_long_constant. The zend_register_long_constant function assigns the type, value, name, and module number of the constants to the new zend_constant. Call zend_register_constant to add it to the global Constant list.
Php_cgi_startup ()-> php_module_startup ()-> zend_startup ()-> zend_register_standart_constant ()-> zend_register_constant
ZEND_API void zend_register_long_constant(const char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC){ zend_constant c; c.value.type = IS_LONG; c.value.value.lval = lval; c.flags = flags; c.name = zend_strndup(name, name_len-1); c.name_len = name_len; c.module_number = module_number; zend_register_constant(&c TSRMLS_CC);}
The zend_register_constant function first determines whether to be case sensitive Based on c-> flags in the constant. If not, the names are all lowercase. If "\" is included, the names are all lowercase. Otherwise, the name is defined and the following statement is called to add the current constant to EG (zend_constant ). EG (zend_constants) is a HashTable. The following Code adds a constant to this HashTable
zend_hash_add(EG(zend_constants), name, c->name_len, (void *) c,、 sizeof(zend_constant), NULL)==FAILURE)
In the php_module_startup function, except that the zend_startup function has registered standard constants, it registers some constants through the macro REGISTER_MAIN_LONG_CONSTANT, such as PHP_VERSION and PHP_ OS.