The variable that we use in PHP is a struct in the underlying C language code, consisting of four members
typedef struct _ZVAL_STRUCT { zvalue_value value; /* The value of the variable is also a struct */ zend_uint refcount__gc; /* Variable reference count typedef unsigned INT zend_uint */ Zend_uchar type; /* Variable type typedef unsigned char Zend_uchar */ Zend_uchar is_ref__gc; typedef unsigned CHAR Zend_uchar */
} Zval;
typedef Union _ZVALUE_VALUE { long lval; /* Long integer, storage integer, BOOL, resource type */ double dval; /* float, store decimal */ struct { char *val; int Len; /* */ } str; /* String, Val is the string pointer, Len is the string length */ HashTable *ht; /* Hashtable is the PHP array */ zend_object_value obj; /* PHP Object */} Zvalue_value;
The type of PHP variable, that is, the type member of Zval, a total of 8 kinds
| type |
members stored in the Zvalue_value |
Description |
IS_NULL |
Do not store values |
Null |
IS_LONG |
Lval |
Integral type |
IS_DOUBLE |
Dval |
Floating point Type |
IS_BOOL |
Lval |
Boolean |
| Is_resource |
Lval |
Resources |
| Is_string |
Str |
String |
IS_ARRAY |
Ht |
Array |
IS_OBJECT |
Obj |
Object |
These types are macro definitions and can be found in zend/zend.h
1 #define Is_null 02 #define Is_long 13 #Define is_double 24 #define Is_bool 35 #define Is_array 46 #define Is_object 57 #Define is_string 68 #Define Is_resource 7
Usually we do not directly use PHP variable members, such as Zval->type or Zvalue_value->lval, for code compatibility, Zend provides us with a lot of API to facilitate our operation of variables
| macro Definition Prototypes |
Get variable |
Description |
zend_uchar Z_TYPE(zval zv) |
Type |
Return variable type |
long Z_LVAL(zval zv) |
Value.lval |
Returns the Lval member of Zvalue_value |
zend_bool Z_BVAL(zval zv) |
Value.lval |
Returns the Lval member of the Zvalue_value and converts it to the Zend_bool type |
double Z_DVAL(zval zv) |
Value.dval |
|
long Z_RESVAL(zval zv) |
Value.lval |
Returns the Lval member of the Zvalue_value, at which point the type is Is_resource |
char* Z_STRVAL(zval zv) |
Value.str.val |
Returns the value of a string |
int Z_STRLEN(zval zv) |
Value.str.len |
Returns the length of a string |
HashTable* Z_ARRVAL(zval zv) |
Value.ht |
Returns a hashtable that is an array |
zend_object_value Z_OBJVAL(zval zv) |
Value.obj |
Returns objectvalue |
uint Z_OBJ_HANDLE(zval zv) |
Value.obj.handle |
Returns the object handle for objectvalue |
zend_object_handlers* Z_OBJ_HT_P(zval zv) |
Value.obj.handlers |
Returns the handler table for objectvalue |
zend_class_entry* Z_OBJCE(zval zv) |
Value.obj |
Returns the class entry for objectvalue |
HashTable* Z_OBJPROP(zval zv) |
Value.obj |
Returns the properties of objectvalue |
HashTable* Z_OBJPROP(zval zv) |
Value.obj |
Returns the properties of objectvalue |
HashTable* Z_OBJDEBUG(zval zv) |
Value.obj |
If an object has the Get_debug_info handler set, it's called, else Z_objprop is called |
These APIs are actually macro definitions, each of the macros listed above has two other similar definitions, taking Z_type as an example
#define Z_TYPE(zval) (zval).type //参数是zval
#define Z_TYPE_P(zval_p) Z_TYPE(*zval_p) //参数是zval的指针
#define Z_TYPE_PP(zval_pp) Z_TYPE(**zval_pp) //参数是zval的指针的指针These macro definitions can be found in the Zend/zend_operators.h
1 #define Z_lval (Zval) (zval). Value.lval2 #define Z_bval (Zval) ((Zend_bool) (zval). Value.lval)3 #define Z_dval (Zval) (zval). Value.dval4 #define Z_strval (Zval) (zval). Value.str.val5 #define Z_strlen (Zval) (zval). Value.str.len6 #define Z_arrval (Zval) (zval). value.ht7 #define Z_ast (Zval) (zval). Value.ast8 #define Z_objval (Zval) (zval). Value.obj9 #define Z_obj_handle (Zval) z_objval (zval). HANDLETen #define Z_OBJ_HT (Zval) z_objval (zval). Handlers One #define Z_OBJCE (Zval) zend_get_class_entry (& (Zval) tsrmls_cc) A #define Z_objprop (Zval) z_obj_ht ((Zval))->get_properties (& (Zval) tsrmls_cc) - #define Z_obj_handler (Zval, HF) Z_obj_ht ((zval))->HF - #define Z_resval (Zval) (zval). Value.lval the #define Z_OBJDEBUG (zval,is_tmp) (Z_obj_handler ((zval), get_debug_info)? Z_obj_handler ((zval), Get_debug_info) (& (Zval), &is_tmp tsrmls_cc):(Is_tmp=0,z_obj_handler ((zval), get_ Properties)? Z_objprop (zval): NULL)) - - #define Z_LVAL_P (zval_p) z_lval (*zval_p) - #define Z_BVAL_P (zval_p) z_bval (*zval_p) + #define Z_DVAL_P (zval_p) z_dval (*zval_p) - #define Z_STRVAL_P (zval_p) z_strval (*zval_p) + #define Z_strlen_p (zval_p) Z_strlen (*zval_p) A #define Z_ARRVAL_P (zval_p) z_arrval (*zval_p) at #define Z_AST_P (zval_p) z_ast (*zval_p) - #define Z_OBJPROP_P (zval_p) z_objprop (*zval_p) - #define Z_objce_p (zval_p) z_objce (*zval_p) - #define Z_RESVAL_P (zval_p) z_resval (*zval_p) - #define Z_OBJVAL_P (zval_p) z_objval (*zval_p) - #define Z_obj_handle_p (zval_p) z_obj_handle (*zval_p) in #define Z_OBJ_HT_P (zval_p) z_obj_ht (*zval_p) - #define Z_OBJ_HANDLER_P (zval_p, h) z_obj_handler (*zval_p, h) to #define Z_objdebug_p (zval_p,is_tmp) z_objdebug (*zval_p,is_tmp) + - #define Z_LVAL_PP (ZVAL_PP) z_lval (**zval_pp) the #define Z_BVAL_PP (ZVAL_PP) z_bval (**zval_pp) * #define Z_DVAL_PP (ZVAL_PP) z_dval (**zval_pp) $ #define Z_STRVAL_PP (ZVAL_PP) z_strval (**zval_pp)Panax Notoginseng #define Z_STRLEN_PP (ZVAL_PP) Z_strlen (**zval_pp) - #define Z_ARRVAL_PP (ZVAL_PP) z_arrval (**zval_pp) the #define Z_AST_PP (zval_p) z_ast (**zval_p) + #define Z_OBJPROP_PP (ZVAL_PP) z_objprop (**zval_pp) A #define Z_OBJCE_PP (ZVAL_PP) z_objce (**zval_pp) the #define Z_RESVAL_PP (ZVAL_PP) z_resval (**zval_pp) + #define Z_OBJVAL_PP (ZVAL_PP) z_objval (**zval_pp) - #define Z_OBJ_HANDLE_PP (zval_p) z_obj_handle (**zval_p) $ #define Z_OBJ_HT_PP (zval_p) z_obj_ht (**zval_p) $ #define Z_OBJ_HANDLER_PP (zval_p, h) z_obj_handler (**zval_p, h) - #define Z_OBJDEBUG_PP (zval_pp,is_tmp) z_objdebug (**zval_pp,is_tmp)
In addition to getting types and values, there are some operations related to the REFCOUNT__GC and is_ref__gc of L variables
| macro Definition Prototypes |
Description |
zend_uint Z_REFCOUNT(zval zv) |
Returns the value of the REFCOUNT__GC |
zend_uint Z_SET_REFCOUNT(zval zv) |
Sets the refcount__gc of the Zval variable and returns |
zend_uint Z_ADDREF(zval zv) |
++ZVAL->REFCOUNT__GC and return |
zend_uint Z_DELREF(zval zv) |
--ZVAL->REFCOUNT__GC and return |
zend_bool Z_ISREF(zval zv) |
Back to ZVAL->IS_REF__GC |
void Z_UNSET_ISREF(zval zv) |
Set IS_REF__GC to 0 |
void Z_SET_ISREF(zval zv) |
Set IS_REF__GC to 1 |
void Z_SET_ISREF_TO(zval zv, zend_uchar to) |
Set IS_REF__GC toto |
These macro definitions also have versions of *_p or *_PP that can be viewed in zend/zend.h
1 #define Z_REFCOUNT_PP (PPZ) z_refcount_p (* (PPZ) )2 #define Z_SET_REFCOUNT_PP (PPZ, RC) z_set_refcount_p (* (PPZ), RC)3 #define Z_ADDREF_PP (PPZ) z_addref_p (* (PPZ) )4 #define Z_DELREF_PP (PPZ) z_delref_p (* (PPZ) )5 #define Z_ISREF_PP (PPZ) z_isref_p (* (PPZ) )6 #define Z_SET_ISREF_PP (PPZ) z_set_isref_p (* (PPZ) )7 #define Z_UNSET_ISREF_PP (PPZ) z_unset_isref_p (* (PPZ) )8 #define Z_SET_ISREF_TO_PP (Ppz, ISREF) z_set_isref_to_p (* (PPZ), ISREF)9 Ten #define Z_REFCOUNT_P (PZ) zval_refcount_p (PZ) One #define Z_SET_REFCOUNT_P (PZ, RC) zval_set_refcount_p (PZ, RC) A #define z_addref_p (PZ) zval_addref_p (PZ) - #define z_delref_p (PZ) zval_delref_p (PZ) - #define z_isref_p (PZ) zval_isref_p (PZ) the #define z_set_isref_p (PZ) zval_set_isref_p (PZ) - #define z_unset_isref_p (PZ) zval_unset_isref_p (PZ) - #define Z_set_isref_to_p (PZ, ISREF) zval_set_isref_to_p (PZ, ISREF) - + #define Z_refcount (z) z_refcount_p (& (z)) - #define Z_set_refcount (z, RC) z_set_refcount_p (& (z), RC) + #define Z_ADDREF (z) z_addref_p (& (z)) A #define Z_DELREF (z) z_delref_p (& (z)) at #define Z_ISREF (z) z_isref_p (& (z)) - #define Z_SET_ISREF (z) z_set_isref_p (& (z)) - #define Z_UNSET_ISREF (z) z_unset_isref_p (& (z)) - #define Z_SET_ISREF_TO (Z, ISREF) z_set_isref_to_p (& (z), ISREF)
We will frequently use the API operations provided by these Zend during the development of the extension, you do not need to write it down, and as the development progresses, you will gradually become accustomed to the use of these APIs.
PHP Extension Development-variables