php扩展开发学习笔记 8

hash

  在php中,许多东西都是hash表。除了显而易见的数组以外,其实对象的属性,函数入口表、变量的符号表等在php内部也都是使用hash表来保存的。事实上,hash表里可以放任何一种数据类型的指针,并不限于zval*。

  hash表的C结构叫HashTable。如果要创建一个HashTable,一般的做法如下:
HashTable *ht;
ALLOC_HASHTABLE(ht);
这样就会创建一个HashTable,并把地址放在ht里。光有一个HashTable结构还是不行的,还需要初始化。这就需要用到zend_hash_init函数。声明如下:
int zend_hash_init(
    HashTable *ht,
    uint nSize,
    hash_func_t pHashFunction,
    dtor_func_t pDestructor,
    zend_bool persistent
)
第一个参数就是一个HashTable指针,必须是已经分配好内存的。
nSize是初始大小,就是存放东西的个数。超过这个值时会自动扩展。如果这个值不是2的n次方,则会自动变成大于它的最小的2的n次方数。
pHashFunction是没用的,但为了向下兼容,这个参数还在那里。必须为NULL。
pDestructor是析构函数。一般使用ZVAL_PTR_DTOR。
最后那个参数persistent是表示是用emalloc还是pemalloc来分配内存。

  php的hash表可以有整数和字符串两种键,然后就有了两套访问hash表的函数。hash相关函数都以zend_hash_开头。例如:
int zend_hash_update(HashTable *ht, char *arKey, uint nKeyLen,  void *pData, uint nDataSize, void **pDest);
用来更新字符串键的值。arKey是键;nKenLen是键的长度,包括最后的’’;pData是值数据的指针,nDataSize是数据指针的大小。最后一个参数是用来指定值数据指针的保存位置的,对于更新操作一般用NULL即可而对于读取操作,则用来放取出的值的指针。一个调用的例子:
zend_hash_update(pHash, “hello”, sizeof(“hello”), &pZval, sizeof(zval*), NULL);
其他几个hash操作函数也大同小异。
zend_hash_index_update用来更新整数键的值,zend_hash_find和zend_hash_index_find分别用来读取字符串键和整数键所对应的值;zend_hash_exists和zend_hash_index_exists用来判断指定的键是否存在;zend_hash_del和zend_hash_index_del用于删除。还有许多其他的hash操作函数。zend_hash_num_elements用于得到元素的个数;zend_hash_clean用于清除全部元素;zend_hash_destroy除了清除全部元素外,还会释放由zend_hash_init所分配的内存,彻底销毁hash表。

 

2 thoughts on “php扩展开发学习笔记 8

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.