In applications, define is often used to define common parameter information to increase program readability and reliability.
In PHP, the constant name is a simple identifier, which cannot be changed during the execution period and is case sensitive by default. Constants are always capitalized.
Note: The third parameter in define can be used to set whether the constant name is case sensitive.
1. Internal Structure of constants
Typedef struct _ zend_constant {zval value;/* zval structure, storage structure of PHP internal variables */INT flags;/* constant tags such as const_persistent | const_cs */char * Name; /* constant name */uint name_len;/* constant name character length */INT module_number;/* module number */} zend_constant;
Ii. Defining constants in PHP
<?phpdefine('DATABASE', 'MYSQL');define('DATABASE_USER', 'ROOT');define('DATABASE_PASSWORD', 'PASSWORD');
3. Analysis of opcode
# PHP-dvld. Active = 1 index. php
Print the opchode, as shown in figure
Note: To view the opcode extension VLD installation, read "Analysis of PHP opcode through VLD extension".
The following three commands are described: send_val, do_fcall, and return.
Send_val: fixed parameter value, operation code 65
Return: return the result from the function. The operation code is 62.
Do_fcall: Call function, operation code 60
More instructions: http://php.net/manual/en/internals2.opcodes.list.php
4. Run opcode through Zend VM
Void zif_define (int ht, zval * return_value, zval ** return_value_ptr, zval * this_ptr, int return_value_used) zend_function (define) {char * Name; int name_len; zval * val; zval * val_free = NULL; zend_bool non_cs = 0; // receives the third parameter, which is case sensitive. Int case_sensitive = const_cs; zend_constant C by default; // The struct variable corresponding to the constant in PHP/** SZ | B function define (string, zval [, Boolean]) * this parameter indicates defining the received parameter, and S is a string, Z is zval, B is Boolean **/If (zend_parse _ Parameters (zend_num_args () tsrmls_cc, "SZ | B", & name, & name_len, & Val, & non_cs) = failure) {return;} If (non_cs) {case_sensitive = 0;}/* class constant, check if there is name and make sure class is valid & exists */If (zend_memnstr (name ,"::", sizeof (":")-1, name + name_len) {zend_error (e_warning, "class constants cannot be defined or redefined"); return_false;} repeat: switch (z_type_p (VAL) {ca Se is_long: Case is_double: Case is_string: Case is_bool: Case is_resource: Case is_null: break; // above, integer, float, String, Boolean, and nullcase is_object are allowed: /* if an object is input, you can determine whether to define the _ tostring () magic method and reset the Val value. * You can see that define has accepted the object as a parameter, the precondition is that _ tostring () is defined, and the returned values are integer, float, String, Boolean, and null *. At this time, the version here is php5.3.8 **/If (! Val_free) {If (z_obj_ht_p (VAL)-> get) {val_free = val = z_obj_ht_p (VAL)-> get (Val tsrmls_cc); goto repeat ;} else if (values (VAL)-> cast_object) {alloc_init_zval (val_free); If (z_obj_ht_p (VAL)-> cast_object (Val, val_free, is_string tsrmls_cc) = success) {val = val_free; break ;}}/ * No break */Default: // if it is of another type, the error zend_error (e_warning, "constants may only evaluate to scalar values") is returned "); if (val_free) {zval_ptr_dtor (& val_free) ;}return_false;} 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 ;}}