


How does PHP store variables? Do you understand the zval structure?
zval in PHP source code
There is no need to declare a type when defining a variable in PHP. Initially, an integer value is assigned to the variable $a, and it can be easily changed to other types later. . So how is this variable $a stored in the PHP source code? With this question in mind, let’s take a look at the source code of PHP.
The source code of PHP is written in C. A zval structure is used in the PHP source code to store the variables created in the PHP code. Let’s take out the definition of the zval structure and briefly analyze it.
This is PHP’s official repository on Github: github.com/php/php-src. The branch used in this article is PHP-7.4.29.
zval structure
Find this file in the PHP source code: php-src/Zend/zend_types.h, you can see that the zval structure is defined as follows , the left side is the source code. The source code uses PHP's own defined types zend_uchar, uint16_t, uint32_t, etc. These types will be converted to char short int, etc. under different platforms and compilers for the platform. For ease of understanding, I translated it into a common type and displayed it on the right side of the source code. At the same time, the macro function ZEND_ENDIAN_LOHI_3() is also expanded.
typedef struct _zval_struct zval; ... 《源代码》 《翻译后》 ------------------------------------------------------------------------------------------- struct _zval_struct { | struct _zval_struct { zend_value value; | zend_value value; union { | union { struct { | struct { ZEND_ENDIAN_LOHI_3( | unsigned char type; zend_uchar type, | unsigned char type_flags; zend_uchar type_flags, | union { union { | unsigned short extra; uint16_t extra; | } u; } u | } v; ) | unsigned int type_info; } v; | } u1; uint32_t type_info; | union { } u1; | unsigned int next; union { | unsigned int cache_slot; uint32_t next; | unsigned int opline_num; uint32_t cache_slot; | unsigned int lineno; uint32_t opline_num; | unsigned int num_args; uint32_t lineno; | unsigned int fe_pos; uint32_t num_args; | unsigned int fe_iter_idx; uint32_t fe_pos; | unsigned int access_flags; uint32_t fe_iter_idx; | unsigned int property_guard; uint32_t access_flags; | unsigned int constant_flags; uint32_t property_guard; | unsigned int extra; uint32_t constant_flags; | } u2; uint32_t extra; | }; } u2; | }; |
In the zval structure, the value of the variable is stored in the value attribute of the zend_value type. And use u1.v.type to record the type of this value. For example, IS_LONG corresponds to the integer type, and IS_STRING corresponds to the string type.
zend_value union
zend_value type is also defined in php-src/Zend/zend_types.h. It is a union. The following is the definition of zend_value union. , the left side is the source code. Also on the right side, I also made a simple translation, translating zend_long uint32_t into a common type for easy viewing.
《源代码》 《翻译后》 ------------------------------------------------------------------------------------ typedef union _zend_value { | typedef union _zend_value { zend_long lval; /* long value */ | long lval; double dval; /* double value */ | double dval; zend_refcounted *counted; | zend_refcounted *counted; zend_string *str; | zend_string *str; zend_array *arr; | zend_array *arr; zend_object *obj; | zend_object *obj; zend_resource *res; | zend_resource *res; zend_reference *ref; | zend_reference *ref; zend_ast_ref *ast; | zend_ast_ref *ast; zval *zv; | zval *zv; void *ptr; | void *ptr; zend_class_entry *ce; | zend_class_entry *ce; zend_function *func; | zend_function *func; struct { | struct { uint32_t w1; | unsigned int w1; uint32_t w2; | unsigned int w2; } ww; | } ww; } zend_value; | } zend_value;
One characteristic of the union is that the memory it occupies is the length corresponding to the largest type in its attributes. Among them, zend_long is of type long. You can see that the length of lval of long type and dval of double type are both 8 bytes. Other pointer types inside are also 8 bytes. The last structure attribute ww is composed of two int types, and the combined length is also 8 bytes. The length of this union is therefore 8 bytes.
In the PHP code we write, the values of integer and floating point data will be stored directly in lval and dval. If it is a string, array or other types, a space will be allocated to store the data, and its address will be stored in zend_value, which is the zval.value attribute, such as: zval.value.zend_long = 9527, zval.value.zend_string = character String address, zval.value.zend_array = array address. Then mark on zval.u1.v.type that this zval.value is an integer, floating point, string, or other type.
zval.u1.v.type type definition is also in the php-src/Zend/zend_types.h file. All definitions are as follows:
/* 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_AST 11 /* internal types */ #define IS_INDIRECT 13 #define IS_PTR 14 #define IS_ALIAS_PTR 15 #define _IS_ERROR 15 /* fake types used only for type hinting (Z_TYPE(zv) can not use them) */ #define _IS_BOOL 16 #define IS_CALLABLE 17 #define IS_ITERABLE 18 #define IS_VOID 19 #define _IS_NUMBER 20
zval structure memory usage
Next we analyze the memory required by zval.
value: zend_value type 8 bytes.
u1:
u1.v.type: unsigned char 1 byte, u1.v.type_flags : unsigned char 1 byte, u1.v.u: There is only one unsigned short extra attribute in the union of 2 bytes, so the structure of u1.v is 4 bytes in total.
u1.type_info: unsigned int 4 bytes.
So the length of the union u1 is the length of the longest attribute: 4 bytes.
u2: It is also a union, which contains int-type attributes, so the length is 4 bytes.
So the total memory occupied by zval is 8 4 4 = 16 bytes.
That is to say, when we write PHP code, if we create an integer variable, it will actually occupy 16 bytes of memory during operation, memory overhead At least twice as long as C language. Of course, this double overhead also brings PHP's flexibility in handling variables.
Recommended learning: "PHP Video Tutorial"
The above is the detailed content of How does PHP store variables? Do you understand the zval structure?. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.
