Understanding PHP 8 Internal Array Structure (zend_array)

This article explains PHP 8’s internal array implementation, describing the zend_array (alias zend_array and HashTable) structure, its key‑value storage, ordering, and the detailed fields such as reference counting, flags, bucket data, and associated functions, providing code excerpts for deeper understanding.

php Courses
php Courses
php Courses
Understanding PHP 8 Internal Array Structure (zend_array)

PHP arrays are used not only in variables (as array pointers in zval) but also frequently within the engine, such as in symbol tables.

In PHP 8, arrays are represented by _zendarray, aliased as zend_array and HashTable.

The two aliases exist for backward compatibility with older functions and macros that may reference either HashTable or zend_array.

In PHP, an array is a "bidirectional ordered multidimensional linked list".

It has two characteristics:

1) It stores key‑value pairs.

2) It is ordered.

It can be understood as an advanced hash table.

In PHP 8, the array definition resides in zend_types.h, and the core code is as follows:

typedef struct _zend_array      zend_array;   //别名zend_array
typedef struct _zend_array HashTable; //别名 HashTable
struct _zend_array {
zend_refcounted_h gc; 
//和zend_string一样   还记得前面的zend_string 吗?
///  gc  占用8个字节 用于引用计数和  字符串类型的记录
union {
struct {
ZEND_ENDIAN_LOHI_4(
zend_uchar    flags,
//#define HASH_FLAG_CONSISTENCY     ((1<<0) | (1<<1))
//#define HASH_FLAG_PACKED           (1<<2)
//#define HASH_FLAG_UNINITIALIZED    (1<<3)
//#define HASH_FLAG_STATIC_KEYS      (1<<4) /* long and interned strings */
//#define HASH_FLAG_HAS_EMPTY_IND    (1<<5)
//#define HASH_FLAG_ALLOW_COW_VIOLATION (1<<6)
zend_uchar    _unused,
zend_uchar    nIteratorsCount,
//迭代器计数。foreach语句会在全局变量EG中创建一个迭代器,
//迭代器包含正在遍历的HashTable和游标信息。
//nIteratorsCount记录了当前runtime正在迭代当前HashTable的迭代器的数量。
zend_uchar    _unused2)
} v;
//这里有点不一样 看陈雷大佬书中 v结构体还包括 u.v.nApplyCount和u.v.consistency
uint32_t flags;
} u;
// u是是一个联合体。占用4个字节。
//可以存储一个uint32_t类型的flags,也可以存储由4个unsigned char组成的结构体v,
//这里的宏ZEND_ENDIAN_LOHI_4是为了兼容不同操作系统的大小端,可以忽略。
Bucket           *arData;
//HashTable中存储数据的单元的指针。
//  用来存储key和value以及辅助信息的容器。
uint32_t          nTableSize;
//    HashTable的大小。表示arData指向的bucket数组的大小,即所有bucket的数量。
//该字段取值始终是2n,最小值是8,最大值在64位系统中是0x80000000(2的31次幂)。
uint32_t          nNumUsed;
//指所有已使用bucket的数量,包括有效bucket和无效bucket的数量
uint32_t          nNumOfElements;
//有效bucket的数量。该值总是小于或等于nNumUsed
uint32_t          nTableMask;
//标记。一般值为  -nTableSize。
uint32_t          nInternalPointer;
//全局默认游标。reset/key/current/next/prev等宏 和操作都会用到
zend_long         nNextFreeElement;
//下一个插入的元素的key的下标  
//比如  当$a[] = 1  nNextFreeElement =1  
dtor_func_t       pDestructor;
//指向一个函数   typedef void (*dtor_func_t)(zval *pDest);
//可以看出是pDest是zval结构指针二级指针,
//为什么会是二级指针,因为c语言函数传递都是值传递,要改变指针值只能将指针地址传入
//当bucket元素被更新或者被删除时,会对bucket的value调用该函数,
//如果value是引用计数的类型,那么会对value引用计数减1,进而引发可能的gc。
};
typedef struct _zend_refcounted_h {
uint32_t         refcount;//一个 32位纯数字的 refcount
uint32_t type_info;
} u;
} zend_refcounted_h;
//_zend_refcounted_h
// 包括 一个 32位纯数字的 refcount 和一个联合体u 
//联合体u里面包括一个 type_infozend_refcounted_h 占用8字节,refount英文翻译成中文是引用的意思 显然 这个 zend_refcounted_h是为了引用计数和字符串类别存储用的。
typedef struct _Bucket {
zval              val;  
//数组的值 ( 复习下 zval只有16个字节)
zend_ulong         h;     // key的 hash值
zend_string      *key;      //数组的key的 指针      /* string key or NULL for numerics */
} Bucket;
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendPHParray-internalszend_array
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

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.