Learn PHP kernel 7 (vi): The Zval of variables

Source: Internet
Author: User

Remember that the Internet is widely circulated "PHP is the best language in the world", for the moment not to discuss whether it is exaggerated, but at least PHP does have a unique advantage, such as its weak type, that is, only the $ sign to declare variables, so that PHP threshold is very low to become the preferred Web server language. So how is the variable implemented? Let's learn the basic variables of PHP today.

First, Introduction

PHP variables are stored in the ZVAL structure and can be seen zval when compiled into Op_array in the execution phase. The structure is defined in the Zend/zend_types.h definition content as follows:

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;};
II. Structure Analysis 2.1, Zend_value

The first variable of the struct is Zend_value, as the name implies, it is also a struct, used to store the value of a variable, such as Integer, float, reference count, String, array, object, resource, and so on. zend_valueMany types of pointers are defined, but these types are not all types of variables, and some are used by the kernel itself, such as pointer 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 is a consortium that unites structures v and integral types type_info . Let's look v at the composition of the structure first.

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 refers to the types of variables, just in the 2.1 Zend_value is used to store the value of the variable, so there should be a place to store the variable type, and this is the role of type. The following are all the variable types defined by PHP, with the types of Boolean, NULL, floating point, Array, String, and so on known to us. There are also unfamiliar undef, indirect, PTR types, variable types are explained in the next chapter, and are not described here.

/* regular data types */#define IS_UNDEF                    0#define IS_NULL                     1#define IS_FALSE                    2#define IS_TRUE                     3#define IS_LONG                     4#define IS_DOUBLE                   5#define IS_STRING                   6#define IS_ARRAY                    7#define IS_OBJECT                   8#define IS_RESOURCE                 9#define IS_REFERENCE                10/* constant expressions */#define IS_CONSTANT                 11#define IS_CONSTANT_AST             12/* fake types */#define _IS_BOOL                    13#define IS_CALLABLE                 14/* internal types */#define IS_INDIRECT                 15#define IS_PTR                      17
2.2.2, Type_flags

It can be understood as a subtype, which refers to the type of the variable, which is for different types of subtypes or tags, type_flags altogether the following 6 kinds.

/* zval.u1.v.type_flags */#define IS_TYPE_CONSTANT            (1<<0)  /* 常量 */#define IS_TYPE_IMMUTABLE           (1<<1)  /* 不可变的类型 */#define IS_TYPE_REFCOUNTED          (1<<2)  /* 需要引用计数的类型 */#define IS_TYPE_COLLECTABLE         (1<<3)  /* 可能包含循环引用的类型 */#define IS_TYPE_COPYABLE            (1<<4)  /* 可被复制的类型 */#define IS_TYPE_SYMBOLTABLE         (1<<5)  /* 符号表类型 */
2.2.3, Const_flags

The tag for the constant type, the corresponding property is:

/* zval.u1.v.const_flags */#define IS_CONSTANT_UNQUALIFIED     0x010#define IS_LEXICAL_VAR              0x020#define IS_LEXICAL_REF              0x040#define IS_CONSTANT_CLASS           0x080  /* __CLASS__ in trait */#define IS_CONSTANT_IN_NAMESPACE    0x100  /* used only in opline->extended_value */
2.2.4, Type_info

Type_info and struct v share memory, modifying Type_info is equivalent to modifying the value of struct V, so type_info is a combination of four char in V.

2.3, U2

U1 and Zend_value can be used to represent variables, there is no need to define U2, but let's take a look, if there is no U2, in the case of memory alignment zval memory size is 16 bytes, when the union of U2 still occupies 16 bytes. Since there is or is not occupying the same amount of memory, it is better to use it to record some ancillary information. Let's look at what is stored in U2.

2.3.1, Next

Used to resolve the problem of the hash conflict and record the next element location of the conflict.

2.3.2, Cache_slot

Run-time caching, which is returned to the cache when the function is executed, and is found in the global function table if it is not in the cache.

2.3.3, Lineno

The line number of the file execution, applied on the AST node. The Zend Engine records the line number of the currently executed file in lexical and syntactic parsing and records it in the Lineno in Zend_ast.

2.3.4, Num_args

The number of arguments passed into the function when the function is called.

2.3.5, Fe_pos

The location where the current traversal is logged when iterating through an array, such as Fe_pos each time a foreach is executed, and when the foreach is called again for traversal, Fe_post resets.

2.3.6, Fe_iter_idx

This is similar to Fe_pos, except that it is object-oriented. The properties of the object are also hashtable, and when the passed parameter is an object, it gets the properties of the object, so traversing the object is the property of the Variable object.

Iii. Reference Documents
    • Anatomy of the PHP7 kernel
    • "PHP7 bottom design and source code implementation"
    • Deep understanding of the zval of the PHP7 kernel
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

Tags Index: