跟厂长学PHP内核7(六):变量之zval

 记得网上流传甚广的段子“PHP是世界上最好的语言”,暂且不去讨论是否言过其实,但至少PHP确实有独特优势的,比如它的弱类型,即只需要$符号即可声明变量,使得PHP入手门槛极低,成为大家所青睐的Web服务端语言。那么它的变量是如何实现的呢?我们今天就来学习一下PHP的基本变量。

一、引言

PHP的变量存储在zval结构体中,在执行阶段中编译为op_array时就能看到zval的身影。结构体定义在Zend/zend_types.h中,定义内容如下所示:

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)     /* 保留字段 */         } v;         uint32_t type_info;     } u1;     union {         uint32_t     var_flags;         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 */     } u2; };

二、结构体剖析

2.1、zend_value

结构体的第一个变量是zend_value,顾名思义,它其实也是一个结构体,用于存放变量的值,比如整型、浮点型、引用计数、字符串、数组、对象、资源等。zend_value定义了众多类型的指针,但这些类型并不都是变量的类型,有些是给内核自己使用的,比如指针ast、zv、ptr。

typedef union _zend_value {     zend_long         lval;             /* 整型 */     double            dval;             /* 浮点型 */     zend_refcounted  *counted;          /* 引用计数 */     zend_string      *str;              /* 字符串 */     zend_array       *arr;              /* 数组 */     zend_object      *obj;              /* 对象 */     zend_resource    *res;              /* 资源 */     zend_reference   *ref;              /* 引用 */     zend_ast_ref     *ast;              /* 抽象语法树 */     zval             *zv;               /* zval类型 */     void             *ptr;              /* 指针类型 */     zend_class_entry *ce;               /* class类型 */     zend_function    *func;             /* function类型 */     struct {         uint32_t w1;         uint32_t w2;     } ww; } zend_value;

2.2、u1

u1是一个联合体,它联合了结构体v和整型type_info。下面我们先来看一下结构体v的构成。

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;

2.2.1、type

type是指变量的类型,刚在2.1中讲到了zend_value是用来存储变量的值,所以也应该有地方存储变量的类型,而这就是type的职责。以下是PHP定义的所有变量类型,有我们熟知的布尔、NULL、浮点、数组、字符串等类型。也有陌生的undef、indirect、ptr类型,变量类型在下一章中详解,这里不再赘述。

/* regular data types */

                    
                
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信