ホームページ  >  記事  >  バックエンド開発  >  PHPの変数構造を深く理解する

PHPの変数構造を深く理解する

黄舟
黄舟オリジナル
2017-10-12 09:11:363012ブラウズ

この記事では、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 ビットの場合、この議論は正確ではありません。結果は正しいです。

ただし、CPU が 32 ビットの場合: sizeof(zval) == 16、sizeof(zvalue_value) == 8。主な理由は、CPU が 64 ビットの場合、ポインターは 8 バイトを占有し、32 ビットの場合、ポインターは 4 バイトを占有するためです。 PHP 7 の

zval

// 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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。