当前位置:首页 > PHP

php数组的内部实现

2026-04-03 12:12:09PHP

PHP 数组的内部实现

PHP 的数组是一种混合数据结构,既实现了有序映射(类似字典),又保留了插入顺序。其内部实现经过多次优化,以下是核心机制:

哈希表(HashTable)

PHP 数组底层使用哈希表存储数据,通过散列函数将键名映射到特定槽位。哈希表由两部分组成:

php数组的内部实现

  • 存储桶(Bucket):包含键、值、哈希值及链表指针的结构体
  • 双向链表:维护元素的插入顺序,支持迭代时按插入顺序遍历
// PHP 内核中的 Bucket 结构(简化)
typedef struct _Bucket {
    zval              val;       // 存储的值
    zend_ulong        h;         // 哈希值(数值键直接使用)
    zend_string      *key;       // 字符串键
    struct _Bucket   *next;      // 哈希冲突链表
    struct _Bucket   *prev;      // 双向链表前驱
} Bucket;

动态扩容机制

哈希表会根据元素数量动态调整容量:

php数组的内部实现

  • 初始默认大小为 8 个槽位
  • 当元素数量超过当前容量的 3/4 时触发扩容
  • 新容量为当前容量的 2 倍(直到达到预定义的最大值)

冲突解决

采用链地址法处理哈希冲突:

  • 相同哈希值的元素通过链表连接
  • PHP 7 优化为将冲突链表嵌入到存储桶数组,减少内存访问次数

有序性保证

通过维护双向链表实现有序遍历:

  • 每个 Bucket 包含 prevnext 指针
  • HT 结构保存链表头尾指针,确保 foreach 按插入顺序输出

内存优化(PHP 7+)

  • 打包数组(Packed Array):对连续数字键(0,1,2...)的数组,省略键名存储直接使用索引
  • 内存局部性优化:将 Bucket 与值一起分配,减少 CPU 缓存未命中

性能特性

  • 平均时间复杂度
    • 插入/删除:O(1)
    • 查找:O(1)
  • 内存占用:每个元素约 56 字节(PHP 7+ 优化前为 96 字节)

特殊操作的影响

  • unset() 不会立即释放内存,只是标记为 IS_UNDEF
  • array_splice() 会导致重建双向链表,时间复杂度 O(n)
  • 数值键和字符串键的哈希方式不同:
    $arr = [1 => 'a', "1" => 'b']; // 输出: [1 => "b"](二者哈希值相同)

代码示例观察行为

$array = [];
$array["foo"] = "bar";  // 哈希表插入字符串键
$array[42] = "answer";  // 数值键直接使用整数哈希
unset($array["foo"]);   // 标记 Bucket 为 UNDEF

// 查看内部结构(需安装调试扩展)
debug_zval_dump($array);

通过理解这些机制,可以更高效地使用 PHP 数组,避免如频繁扩容或混合键类型导致的性能下降问题。

标签: 数组php
分享给朋友:

相关文章

git php实现

git php实现

Git 与 PHP 的集成实现 使用 PHP 执行 Git 命令 通过 PHP 的 exec()、shell_exec() 或 passthru() 函数可以直接调用 Git 命令,适用于服务器端操作…

php验证码的实现

php验证码的实现

PHP 验证码实现方法 使用 GD 库生成基础验证码 创建画布并生成随机字符串作为验证码内容: session_start(); $width = 120; $height = 40; $image…

php实现https

php实现https

PHP 实现 HTTPS 请求 在 PHP 中实现 HTTPS 请求,可以通过多种方式完成,包括使用内置函数、cURL 扩展或第三方库。以下是几种常见的方法: 使用 file_get_content…

java如何创建数组

java如何创建数组

创建数组的基本方法 在Java中,数组是固定大小的同类型元素集合。创建数组需要声明数组类型并初始化。 声明数组 语法格式为 数据类型[] 数组名 或 数据类型 数组名[]: int[] arr1;…

react如何创建数组

react如何创建数组

创建数组的方法 在React中创建数组与普通JavaScript相同,可以使用多种方式。以下是常见的几种方法: 使用数组字面量 const array = [1, 2, 3, 4]; 使用Arra…

php实现域名

php实现域名

PHP实现域名操作的方法 获取当前域名 使用$_SERVER['HTTP_HOST']可以获取当前访问的域名: $currentDomain = $_SERVER['HTTP_HOST']; ech…