PHP kernel Zval

Source: Internet
Author: User
Tags php source code

This article mainly introduces the content is about the PHP kernel zval, has a certain reference value, now share to everyone, the need for friends can refer to

Original address
Author: Twei Home

Objective

Before the interview, the interviewer asked how the variables in PHP are implemented, unfortunately, the only answer is probably the structure of the implementation. This article is Google after the conclusion of the comparison in place, so reproduced and then learn.

Body

Data types in PHP

Compared to C, C + +, Java and other programming languages, PHP is a weak type of language, meaning that when we want to use a variable, we do not need to declare its type. This feature brings us a lot of convenience, and sometimes it brings some pitfalls. So, does PHP really have no data type to say?

Of course not. In the official PHP document, the variables in PHP are divided into three classes: scalar types, complex types, and special types. Scalar types include Boolean (bool), integer (int), float (float), and string (strings), complex types include arrays (array) and objects (object), and special types include NULL and resource (Resource). So there are 8 types of data that are broken down by PHP variables.

It is always known that the bottom of PHP is implemented in C language. Our PHP script will go through the Zend engine to parse the C code and execute it. So, how does a PHP variable be represented in the C language? What will it eventually be resolved into?

The answer is Zval. Regardless of the type of PHP variable, in the PHP source code is unified with a structure called zval representation. Zval can be seen as a container for PHP variables in C code, which stores information about the value, type, and so on of the variable.

So let's take a look at the basic structure of zval (requires a little C-language basics).

The basic structure of zval

In the PHP source code zval This structure is a struct _zval_struct (struct) called, specifically defined in the source code of the Zend/zend.h file, the following is an excerpt of the relevant code:

struct _zval_struct {    zvalue_value value;       /* Value */     zend_uint refcount__gc;   /* Value of ref count */    Zend_uchar type;          /* Active type */     Zend_uchar is_ref__gc;    /* If it is a ref variable */}; typedef struct _ZVAL_STRUCT Zval;

That is, in the source code of PHP, this structure is used to represent various types of variables in PHP, and can also implement other functions, such as garbage collection (Gc:grabage Collection).

You can see that it consists of 4 fields that represent some information about the variable.

Zvalue_value VALUE

Value is used to represent the actual value of a variable, specifically it is a zvalue_value union (union):

typedef Union _ZVALUE_VALUE {    long lval;                  /* Long value */    double dval;                /* Double value */    struct {/                    * String */        char *val;        int len;    } STR;    HashTable *ht;              /* Hash table value,used for array */    zend_object_value obj;      /* Object */} Zvalue_value;

You can see that there are only 5 fields in _zvalue_value, but there are 8 types of data in PHP, so how do you use 5 fields to represent 8 types?

This is a clever place for PHP design, and it achieves the purpose of reducing fields by reusing fields. For example, in PHP, the Boolean, Integer, and resource (as long as the identifier of the storage resource) is stored through the Lval field; Dval is used to store floating-point types, str stores strings, HT storage arrays (note that arrays in PHP are actually hash tables), and obj stores object types; A value of 0 or null means NULL in PHP, which means that 5 fields are used to store 8 types of values.

Zend_uint REFCOUNT__GC

As you can see from its suffix GC, this field is related to garbage collection.

It is actually a counter that is used to hold how many variables point to the zval. When a variable is generated, it is set to 1, which is RefCount = 1.

A different operation on a variable changes its value. Typical assignment operations, such as

B will add 1 to the RefCount, while the unset () operation will reduce the corresponding 1.

Garbage collection can be done by judging its value. Before PHP5.3, use the mechanism of reference counting to implement GC: If the refcount of a zval is reduced to 0, then the Zend engine will assume that no variable points to the Zval, freeing up the memory space that the Zval occupies. However, it is not possible to release the zval of the circular reference simply by using the reference counting mechanism, which results in a memory leak (Leak).

Before 5.3, the name of this field is also called refcount,5.3 after the introduction of a new garbage collection algorithm to deal with circular references, the author added a large number of macros to operate the RefCount, in order to make the error faster appearance, so renamed to REFCOUNT__GC, Forcing everyone to use macros to manipulate refcount.

Similarly, there is a fourth field, Is_ref, that indicates whether a type in PHP is a reference.
To learn about PHP's garbage collection mechanism, refer to this blog: PHP garbage collection mechanism
Note: Variables can also be called symbols, symbol. All symbols exist in the symbol table, and different scopes use different symbol tables, which is explained in this blog post.

Zend_uchar TYPE

This field is used to indicate which of the 8 types of PHP a variable belongs to. Within Zend, these types correspond to the following macro (code location PHPSRC/ZEND/ZEND.H):

#define Is_null     0#define is_long     1#define is_double   2#define is_bool     3#define is_array    4#define Is_object   5#define is_string   6#define is_resource 7#define is_constant 8#define is_constant_array   9# Define Is_callable 10

Zend_uchar IS_REF__GC

This field is used to mark whether a variable is a reference variable. For a normal variable, the value is 0, and for a reference-type variable, the value is 1. This variable affects zval sharing, separation, and so on. It is also related to PHP garbage collection.

The Zval in PHP7

The above zval structure, with the development of time, exposed a lot of problems, such as occupy space (24 bytes), do not support expansion, the object and the efficiency of the reference, so in the PHP7 time, the Zval made a large change, and now its structure is this:

struct _zval_struct {union {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;    } 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;};

Although it looks great, but in fact, its fields are all unions, this new zval in a 64-bit environment, it only needs 16 bytes (2 pointers size). The Zval in PHP7 has become a value pointer that either holds the original value or holds a pointer to a saved original value.

This part of the content comes from Brother Bird's GitHub.

Summarize

    1. Zval is a C language implementation of the data structure, function as a container for PHP variables;

    2. It holds various information about variables (such as type and value) and provides support for other functions such as garbage collection;

    3. In different versions of PHP, it has a different structure. The zval of the PHP7 accounts for 16 bytes, and the PHP5 of the two is 24 bytes.

Reference

PHP Kernel Explorer variable (1) Variable container-zval
PHP garbage collection in-depth understanding
Deep understanding of the zval of PHP7

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.