Variables in PHP can save any data type because it is a weakly typed language. But PHP is written in C language. C language is a strongly typed language. Each variable has a fixed type. You cannot change the type of the variable at will (you can force type conversion, but problems may occur). In the zend engine, it is How can a variable save any type?
In the zend/zend.h header file, you will find the following structure:
<code>typedef struct _zval_struct zval; typedef union _zvalue_value { long lval; double dval; struct { char *val; int len; }str; HashTable *ht; zend_object_value obj; } zvalue_value ; struct _zval_struct { zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; }; </code>
The zval structure is the expression of commonly used PHP variables in the kernel. In the zval structure, you can see 4 member variables, namely:
<code>zvalue_value value; //变量的值,PHP变量的值就保存在这里 zend_uint refcount; //变量引用数,变量引用计算器 zend_uchar type; //变量的类型 zend_uchar is_ref; //变量是否被引用 </code>
The value member variable of the zval structure is a zvalue_value union. PHP can maintain any structure type because of this union . As can be seen from the member variables of the zvalue_value union, different types will be saved in different member variables, so that PHP variables can store any data type. For example, when the variable is an integer type, it will be saved to the lval member variable of value; when the variable type is a string, it will be saved to the str member variable of value.
Another question is, how does the zend engine know what type this variable saves? We noticed that there is a type member variable in the zval structure. This member variable is to save the type of a php variable.
The zend engine defines 8 variable types:
<code>#define IS_NULL 0 #define IS_LONG 1 #define IS_DOUBLE 2 #define IS_STRING 3 #define IS_ARRAY 4 #define IS_OBJECT 5 #define IS_BOOL 6 #define IS_RESOURCE 7 </code>
Each macro definition corresponds to a type of the PHP language layer. For example, when the type member variable of zval is equal to IS_STRING (zval.type==IS_STRING
), it means that the type of this variable is a string type.