转载

PHP7内核基础知识之变量类型

前言

下面我们大概了解下PHP7的变量类型都有哪些,是如何存储变量的。

zval结构定义

PHP7中是使用zval结构存储变量信息的。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)     /* call info for EX(This) */   } 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; };

变量的值

通过上面的代码我们可以看到。变量是通过一个_zval_struct结构体方式存储的。其中结构体中的value存储的是变量的值。这个成员是zend_value类型的。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;

zend_value是一个联合体。对于小于64位的简单类型,会直接存储值。如,long double。而对于其他比较复杂的类型,如字符串,数组,对象等,是存储的指针。这样,对于简单类型来说,变得简单高效。

获取变量类型

zval联合体的type存储的是变量的类型。PHP7已经提供了我们获取变量类型的宏方法Z_TYPE。宏方法的定义如下:

static zend_always_inline zend_uchar zval_get_type(const zval* pz) {  return pz->u1.v.type; } #define Z_TYPE(zval)    zval_get_type(&(zval)) #define Z_TYPE_P(zval_p)   Z_TYPE(*(zval_p))

设置变量类型

在PHP7中,设置变量类型提供了新的方法。

#define Z_TYPE_INFO(zval)  (zval).u1.type_info #define Z_TYPE_INFO_P(zval_p)  Z_TYPE_INFO(*(zval_p))

代码实例

下面的代码实现了一个类似var_dump的方法。

PHP_FUNCTION(dump) {     zval *arg;     if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg) == FAILURE) {         return;     }     switch (Z_TYPE_P(arg)) {         case IS_NULL:             RETVAL_STRING("NULL");             break;          case IS_TRUE:             RETVAL_STRING("true");             break;      case IS_FALSE:             RETVAL_STRING("false");             break;          case IS_LONG:             RETVAL_STRING("integer");             break;           case IS_DOUBLE:             RETVAL_STRING("double");             break;          case IS_STRING:             RETVAL_STRING("string");             break;              case IS_ARRAY:             RETVAL_STRING("array");             break;          case IS_OBJECT:             RETVAL_STRING("object");             break;          case IS_RESOURCE:             RETVAL_STRING("resource");             break;          default:             RETVAL_STRING("unknown type");     } }

原文链接: PHP7内核基础知识之变量类型 ,转载请注明来源!

正文到此结束
Loading...