Maison >développement back-end >tutoriel php >Compréhension approfondie de la structure des variables php

Compréhension approfondie de la structure des variables php

黄舟
黄舟original
2017-10-12 09:11:363071parcourir

Cet article présente principalement les connaissances pertinentes sur la structure des variables PHP. L'article mentionne zval en PHP5 et zval en PHP 7. Le code est simple et facile à comprendre. Les amis dans le besoin peuvent s'y référer

<.>zval en PHP5


// 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;
La plupart des articles, lorsqu'ils mentionnent la structure des variables PHP5, mentionnent : sizeof (zval) == 24, sizeof(zvalue_value) == 16. En fait, cette affirmation n'est pas exacte lorsque le processeur est de 64 bits, ce résultat est correct.

Mais lorsque le CPU est en 32 bits : sizeof(zval) == 16, sizeof(zvalue_value) == 8, principalement parce que lorsque le CPU est en 64 bits, le pointeur occupe 8 octets, et lorsque le CPU est en 32 bits, le pointeur fait 4 octets.

zval en PHP 7


// 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;
Il semble y en avoir beaucoup en PHP 7, mais en fait c'est encore plus simple, peu importe que le CPU soit 32 bits ou 64 bits, sizeof(zval) est toujours égal à 16.

Regardez principalement le ww dans zend_value, qui est de deux uint32_t C'est toujours 8 octets, donc sizeof(zend_value) == 8, donc sizeof(zval) == 16.

Donc en termes d'économie de mémoire mentionnée dans les nouvelles fonctionnalités de PHP7, dans les systèmes 32 bits, PHP5 => PHP7 n'a aucun changement.


À propos, sizeof ne peut pas être considéré comme une fonction. Bien qu'elle soit écrite comme une fonction, la valeur sera déterminée au moment de la compilation, pas pendant l'exécution. Semblable au prétraitement de la compilation.

Résumé

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn