この記事では、PHP 変数の構造に関する関連知識を主に紹介します。この記事では、PHP5 の zval と PHP 7 の zval について説明します。コードはシンプルで理解しやすいので、PHP5 の
zval を参照してください。
// 1. zval typedef struct _zval_struct { zvalue_value value; zend_uint refcount__gc; zend_uchar type; zend_uchar is_ref__gc; } zval; // 2. zvalue_value typedef union _zvalue_value { long lval; // 用于 bool 类型、整型和资源类型 double dval; // 用于浮点类型 struct { // 用于字符串 char *val; int len; } str; HashTable *ht; // 用于数组 zend_object_value obj; // 用于对象 zend_ast *ast; // 用于常量表达式(PHP5.6 才有) } zvalue_value; // 3. zend_object_value typedef struct _zend_object_value { zend_object_handle handle; const zend_object_handlers *handlers; } zend_object_value; // 4. zend_object_handle typedef unsigned int zend_object_handle;
ほとんどの記事では、PHP5 の変数構造について言及する際に、sizeof(zval) == 24、sizeof(zvalue_value) == 16 と言及しています。実際、CPU が 64 ビットの場合、この議論は正確ではありません。結果は正しいです。
// 1. zval struct _zval_struct { zend_value value; /* value */ union { struct { ZEND_ENDIAN_LOHI_4( zend_uchar type, /* active type */ zend_uchar type_flags, zend_uchar const_flags, zend_uchar reserved) /* call info for EX(This) */ } v; uint32_t type_info; } u1; union { uint32_t next; /* hash collision chain */ uint32_t cache_slot; /* literal cache slot */ uint32_t lineno; /* line number (for ast nodes) */ uint32_t num_args; /* arguments number for EX(This) */ uint32_t fe_pos; /* foreach position */ uint32_t fe_iter_idx; /* foreach iterator index */ uint32_t access_flags; /* class constant access flags */ uint32_t property_guard; /* single property guard */ } u2; }; // 2. zend_value typedef union _zend_value { zend_long lval; /* long value */ double dval; /* double value */ zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zend_ast_ref *ast; zval *zv; void *ptr; zend_class_entry *ce; zend_function *func; struct { uint32_t w1; uint32_t w2; } ww; } zend_value;
PHP 7 にはたくさんの機能があるように見えますが、実際には、CPU が 32 ビットか 64 ビットかに関係なく、sizeof(zval) は常に 16 に等しくなります。
主に zend_value の ww に注目してください。これは 2 つの uint32_t であり、これは常に 8 バイトであるため、sizeof(zend_value) == 8、つまり sizeof(zval) == 16 になります。
つまり、PHP7 の新機能で述べたメモリの節約という点では、32 ビット システムでは、PHP5 => PHP7 に変更はありません。
ちなみに、sizeofは関数のように書いていますが、値は実行時ではなくコンパイル時に決まります。コンパイルの前処理に似ています。
以上がPHPの変数構造を深く理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。