Backend Development 11 min read

Understanding PHP's zend_string Structure and Memory Management

This article explains the internal PHP7+ data structures such as _zval_struct, zend_value, and zend_string, detailing their fields, type definitions, memory layout, flexible array usage, and the associated allocation and release macros that enable efficient, binary‑safe string handling in the Zend Engine.

php中文网 Courses
php中文网 Courses
php中文网 Courses
Understanding PHP's zend_string Structure and Memory Management

The article begins by examining the struct _zval_struct used in PHP 7+ to represent variables, highlighting its zend_value member and two unused fields u1 and u2 .

It then presents the definition of typedef union _zend_value , which can store integers, doubles, reference‑counted pointers, strings, arrays, objects, resources, references, AST nodes, generic pointers, class entries, functions, and a small custom struct, explaining why a separate boolean type is not needed.

Next, the article lists the 20 type constants defined in zend_types.h , noting that the first eleven are the common runtime types while the rest are internal or hinting types.

The focus shifts to string handling: PHP uses the zend_string structure instead of raw C char* . The structure is defined as:

struct _zend_string {
  zend_refcounted_h gc;   // reference count and type info (8 bytes)
  zend_ulong        h;    // hash value (8 bytes)
  size_t            len;  // length of the string (8 bytes)
  char              val[1]; // flexible array holding the characters
};

The gc field enables reference counting, allowing multiple zvals to share the same string, while the flexible array val[1] provides binary‑safe storage with an explicit length field.

The article explains why the flexible array is declared with size 1 (C99 compatibility) and how the overall struct occupies 25 bytes, rounded to 32 bytes due to alignment.

It then describes the macro‑based workflow for creating a PHP string: zend_string_init calls zend_string_alloc , which allocates memory with pemalloc , sets reference count, type info, hash, and length, then copies the raw characters with memcpy and appends a terminating \0 . The persistent flag determines whether the allocation is request‑bound or permanent.

Finally, the article shows the release macro zend_string_release , which decrements the reference count and frees the memory when it reaches zero.

Throughout, the article provides code snippets, macro explanations, and references to the original source files, encouraging readers to explore the Zend Engine source for deeper understanding.

backendmemory managementString()C languagedata structureszend
php中文网 Courses
Written by

php中文网 Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.