当前位置:Gxlcms > php框架 > 彻底搞懂PHP 变量结构体

彻底搞懂PHP 变量结构体

时间:2021-07-01 10:21:17 帮助过:291人阅读

PHP5 中的 zval

  1. // 1. zval
  2. typedef struct _zval_struct {
  3. zvalue_value value;
  4. zend_uint refcount__gc;
  5. zend_uchar type;
  6. zend_uchar is_ref__gc;
  7. } zval;
  8. // 2. zvalue_value
  9. typedef union _zvalue_value {
  10. long lval; // 用于 bool 类型、整型和资源类型
  11. double dval; // 用于浮点类型
  12. struct { // 用于字符串
  13. char *val;
  14. int len;
  15. } str;
  16. HashTable *ht; // 用于数组
  17. zend_object_value obj; // 用于对象
  18. zend_ast *ast; // 用于常量表达式(PHP5.6 才有)
  19. } zvalue_value;
  20. // 3. zend_object_value
  21. typedef struct _zend_object_value {
  22. zend_object_handle handle;
  23. const zend_object_handlers *handlers;
  24. } zend_object_value;
  25. // 4. zend_object_handle
  26. typedef unsigned int zend_object_handle;

多数文章,在提到PHP5 变量结构体的时候,都提到:sizeof(zval) == 24, sizeof(zvalue_value) == 16,实际上这个论述并不准确,在 CPU 为 64bit 时,这个结果是正确的。

但当 CPU 为32bit 时: sizeof(zval) == 16, sizeof(zvalue_value) == 8,主要因为 CPU 为 64bit 时,指针占用8个字节,而 32bit时,指针为4个字节。

PHP 7 中的 zval

  1. // 1. zval
  2. struct _zval_struct {
  3. zend_value value; /* value */
  4. union {
  5. struct {
  6. ZEND_ENDIAN_LOHI_4(
  7. zend_uchar type, /* active type */
  8. zend_uchar type_flags,
  9. zend_uchar const_flags,
  10. zend_uchar reserved) /* call info for EX(This) */
  11. } v;
  12. uint32_t type_info;
  13. } u1;
  14. union {
  15. uint32_t next; /* hash collision chain */
  16. uint32_t cache_slot; /* literal cache slot */
  17. uint32_t lineno; /* line number (for ast nodes) */
  18. uint32_t num_args; /* arguments number for EX(This) */
  19. uint32_t fe_pos; /* foreach position */
  20. uint32_t fe_iter_idx; /* foreach iterator index */
  21. uint32_t access_flags; /* class constant access flags */
  22. uint32_t property_guard; /* single property guard */
  23. } u2;
  24. };
  25. // 2. zend_value
  26. typedef union _zend_value {
  27. zend_long lval; /* long value */
  28. double dval; /* double value */
  29. zend_refcounted *counted;
  30. zend_string *str;
  31. zend_array *arr;
  32. zend_object *obj;
  33. zend_resource *res;
  34. zend_reference *ref;
  35. zend_ast_ref *ast;
  36. zval *zv;
  37. void *ptr;
  38. zend_class_entry *ce;
  39. zend_function *func;
  40. struct {
  41. uint32_t w1;
  42. uint32_t w2;
  43. } ww;
  44. } zend_value;

PHP 7的看似很多,但其实更简单了,不论 CPU 是32bit 还是 64bit,sizeof(zval) 永远都是等于 16。
主要看 zend_value 中的 ww,是两个 uint32_t,这个永远是 8 个字节,所以 sizeof(zend_value) == 8,因此 sizeof(zval) == 16。

所以 PHP7 新特性提到的节省内存这点上,在 32bit 系统中,PHP5 => PHP7 并无变化。

顺便说下 sizeof,不能当做函数,虽然写法像函数,这个数值会在编译期就确定好,非运行期。类似编译预处理。

总结

以上所述是小编给大家介绍的PHP 变量结构体,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

人气教程排行