Define constant. According to the manual, only constants defined by define are allowed: scalar and null. The scalar type is integer, float, string, or boolean. You can also define the constant value type as resource. see the manual. the constants defined by define are only allowed:
Only scalar and null are allowed. The scalar type is integer, float, string, or boolean. It can also define the type of constant value as resource, but it is not recommended to do so, it may cause unknown conditions.
Today, I read the php source code and found that the second parameter of define can also be an object.
First paste an example:
'Bar' = ('foo', foo;
// Output bar
Next let's take a look at how define is implemented in php:
***val_free == case_sensitive = (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, , &name, &name_len, &val, &non_cs) == = (zend_memnstr(name, , () - , name + (! (Z_OBJ_HT_P(val)->= val = Z_OBJ_HT_P(val)-> (Z_OBJ_HT_P(val)-> (Z_OBJ_HT_P(val)->cast_object(val, val_free, IS_STRING TSRMLS_CC) === & c.value = *&&= case_sensitive; == name_len+= (zend_register_constant(&c TSRMLS_CC) ==
Note that a loop starting with repeat also uses the goto statement T_T
The role of this code is:
- For int, float, string, bool, resource, null, these values are directly used for actually defined constants.
- For an object, you need to convert the object to one of the above six types (if it is still an object after the transformation, the transformation will continue)
How can we convert an object into one of six types? There are two methods in the code:
(Z_OBJ_HT_P (val)-> = val = Z_OBJ_HT_P (val)-> // _ toString () method will be called in cast_object (Z_OBJ_HT_P (val) -> (Z_OBJ_HT_P (val)-> cast_object (val, val_free, IS_STRING TSRMLS_CC) ====
1, Z_OBJ_HT_P (val)-> get. after the macro is expanded, it is (* val). value. obj. handlers-> get
2. Z_OBJ_HT_P (val)-> cast_object. after the macro is expanded, it is (* val). value. obj. handlers-> cast_object
Handlers is a struct containing many function pointers. for specific definitions, see _ zend_object_handlers. The function pointers in this struct are used to operate objects, such as reading/modifying object attributes, obtaining/calling object methods, and so on... get and cast_object are also one of them.
For general objects, php provides the standard cast_object function zend_std_cast_object_tostring, the code is located in php-src/zend/zend-object-handlers.c:
ZEND_API zend_std_cast_object_tostring(zval *readobj, zval *writeobj, type TSRMLS_DC) **= (ce->__tostring &&&readobj, ce, &ce->__tostring, , &retval) ||
From the specific implementation above, the default cast_object is to find the _ tostring method in the class and then call...
Return to the initial example, ('foo ',
('PHP_INT_MAX', 1); ('FOO', 1); ('FOO', 2);
The above code contains two situations: first, we try to redefine the predefined constants of the php kernel, such as PHP_INT_MAX, which will obviously fail. The second case is that we have defined a constant FOO somewhere in the code, and then defined it again in the next program. This will also cause failure. Therefore, it is best to write all the constants that need to be defined together during encoding to avoid duplicate names.
2. constant names are not limited.
It does not have any requirements for its name, and of course it does not need to be a legal php variable name. Therefore, we can let the define constant take some strange names. For example:
('>_<', 123); >_<;
However, if such a constant is defined, it cannot be directly used and a syntax error is reported. The correct method is as follows:
('>_<', 123); ('>_<');
Scalar only allows scalar and null. The scalar type is integer, float, string, or boolean. You can also define the constant value type as resource...