当前位置:首页 > PHP

php hash table 实现

2026-03-13 05:55:29PHP

PHP 哈希表实现

PHP 内部使用哈希表(HashTable)作为核心数据结构,用于实现数组、对象属性表等。哈希表在 PHP 源码中通过 zend_array(即 HashTable 结构体)实现。

哈希表结构

PHP 的哈希表实现主要包含以下关键组件:

php hash table 实现

  • 桶(Bucket):存储实际键值对的结构,包含哈希值、键、值及链表指针。
  • 哈希函数:将键转换为哈希值,PHP 默认使用 DJBX33A 算法。
  • 冲突解决:采用链地址法(拉链法),哈希冲突的桶通过链表连接。

哈希表的核心定义在 Zend/zend_types.hZend/zend_hash.h 中:

php hash table 实现

typedef struct _zend_array HashTable;
struct _zend_array {
    zend_refcounted_h gc;
    union {
        struct {
            ZEND_ENDIAN_LOHI_4(
                zend_uchar    flags,
                zend_uchar    nApplyCount,
                zend_uchar    nIteratorsCount,
                zend_uchar    reserve)
        } v;
        uint32_t flags;
    } u;
    uint32_t          nTableMask;
    Bucket           *arData;      // 存储桶数组
    uint32_t          nNumUsed;    // 已用桶数
    uint32_t          nNumOfElements; // 有效元素数
    uint32_t          nTableSize;  // 哈希表大小(总是 2^n)
    uint32_t          nInternalPointer;
    zend_long         nNextFreeElement;
    dtor_func_t       pDestructor;
};

哈希表操作

插入元素

  1. 计算键的哈希值:hash = zend_string_hash_val(key)
  2. 根据哈希值确定桶的位置:idx = hash & nTableMask
  3. 若发生冲突,将新桶插入链表头部。
  4. 更新哈希表的元信息(如 nNumUsed)。

查找元素

  1. 计算键的哈希值。
  2. 定位到桶的位置,遍历链表比对键值。
  3. 返回匹配的桶或 NULL

扩容机制

当哈希表的负载因子(元素数/桶数)超过阈值时,触发扩容:

  1. 新容量为当前容量的 2 倍(new_size = nTableSize << 1)。
  2. 重新分配 arData 内存,并重建哈希索引。

示例代码(简化版)

以下是一个简化版的哈希表实现逻辑:

// 插入操作示例
void zend_hash_insert(HashTable *ht, zend_string *key, zval *value) {
    uint32_t hash = zend_string_hash_val(key);
    uint32_t idx = hash & ht->nTableMask;
    Bucket *p = ht->arData + idx;

    // 遍历冲突链
    while (p->key != NULL) {
        if (p->key == key || zend_string_equals(p->key, key)) {
            // 键已存在,更新值
            p->val = *value;
            return;
        }
        p = p->next;
    }

    // 新插入桶
    p->key = key;
    p->val = *value;
    p->next = ht->arData[idx].next;
    ht->arData[idx].next = p;
    ht->nNumUsed++;
}

性能优化

  1. 内存局部性arData 同时存储桶和哈希索引,提升缓存命中率。
  2. 惰性删除:删除元素时标记为 UNDEF,延迟内存重整。
  3. 预分配:根据预期元素数初始化哈希表,避免频繁扩容。

PHP 的哈希表实现经过高度优化,支持 O(1) 平均时间复杂度的增删查改操作。

标签: phphash
分享给朋友:

相关文章

php实现递归

php实现递归

递归的基本概念 递归是一种函数调用自身的技术,适用于解决可以分解为相同子问题的问题。在PHP中,递归需要明确的终止条件(基线条件),否则会导致无限循环。 递归实现阶乘 阶乘是经典的递归案例,n! =…

git php实现

git php实现

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

php实现异步

php实现异步

PHP 实现异步的方法 PHP 本身是同步执行的脚本语言,但可以通过以下方法模拟异步操作或实现异步效果: 使用多进程(pcntl_fork) 通过 pcntl_fork 创建子进程实现异步,适用于…

php实现聊天

php实现聊天

实现 PHP 聊天功能的方法 使用 WebSocket 和 PHP 实现实时聊天 WebSocket 是一种全双工通信协议,适合实现实时聊天功能。PHP 可以通过 Ratchet 库实现 WebSo…

php实现博客

php实现博客

使用PHP实现博客系统 数据库设计 创建数据库表存储博客文章和用户信息。常见的表包括posts(文章)和users(用户)。 CREATE TABLE users ( id INT AUTO…

php 队列的实现

php 队列的实现

PHP 队列的实现方法 使用数据库实现队列 创建一个数据表存储队列任务,包含任务ID、状态、创建时间等字段。通过SQL语句实现任务的入队和出队操作。 // 入队操作 INSERT INTO queu…