[翻译][php扩展和嵌入式]第8章-在数组和哈希表上工作
全部翻译内容pdf文档下载地址: http://download.csdn.net/detail/lgg201/5107012
本书目前在github上由laruence(http://www.laruence.com)和walu(http://www.walu.cc)两位大牛组织翻译. 该翻译项目地址为: https://github.com/walu/phpbook
本书在github上的地址: https://github.com/goosman-lei/php-eae
未来本书将可能部分合并到phpbook项目中, 同时保留一份独立版本.
原书名: <Extending and Embedding PHP>
原作者: Sara Golemon
译者: goosman.lei(雷果国)
译者Email: lgg860911@yahoo.com.cn
译者Blog: http://blog.csdn.net/lgg201
在数组和哈希表上工作
在C语言中, 有两种不同的基础方法用来在一个结构体中存储任意数量的独立数据元素. 两种方法都有赞成者和反对者.
向量 Vs. 链表
应用的编写通常基于特定类型数据的特性的选择, 需要存储多少数据, 以及需要多快速度的检索. 为了能够有对等的认知, 我们先来看看简单的看看这些存储机制.
向量
向量是一块连续的内存空间, 它们包含的数据有规律的间隔. 向量最常见的例子就是字符串变量(char *或char []), 它包含了一个接着一个的字符(字节)序列.
常量
含义
ZEND_HASH_APPLY_KEEP
返回这个值将完成当前循环,并继续迭代HashTable中的下一个值.这等价于在foreach()控制块中执行continue;
ZEND_HASH_APPLY_STOP
返回这个值将中断迭代,等价于在foreach()控制块中执行break;
ZEND_HASH_APPLY_REMOVE
类似于ZEND_HASH_APPLY_KEEP,这个返回值将跳到下一次迭代.不过,这个返回值同时会导致从目标HashTable中删除当前元素.
下面是一个简单的用户空间foreach()循环:
常量
含义
HASH_KEY_IS_STRING
当前元素是关联索引的;因此,指向元素key名字的指针将会被设置到strIdx中,它的长度被设置到stdIdxLen中.如果指定了duplicate标记, key的值将在设置到strIdx之前使用estrndup()复制一份.这样做,调用方就需要显式的释放这个复制出来的字符串.
HASH_KEY_IS_LONG
当前元素是数值索引的,索引的数值将被设置到numIdx中
HASH_KEY_NON_EXISTANT
内部指针到达了HashTable内容的末尾.此刻已经没有其他key或数据可用了.
保留内部指针
在迭代HashTable时, 尤其是当它包含用户空间变量时, 少数情况下会碰到循环引用或者说自交的循环. 如果一个迭代上下文的循环开始后, HashTable的内部指针被调整, 接着内部启动了对同一个HashTable的迭代循环, 它就会擦掉原有的当前内部指针位置, 内部的迭代将导致外部的迭代被异常终止.
对于使用zend_hash_apply样式的实现以及自定义的向前移动的用法, 均可以通过外部的HashPosition变量的方式来解决这个问题.
前面列出的zend_hash_*()函数均有对应的zend_hash_*_ex()实现, 它们可以接受一个HashPosition类型的参数. 因为HashPosition变量很少在短生命周期的循环之外使用, 因此将它定义为直接变量就足够了. 接着可以取地址进行使用, 如下示例:
$ php -r 'var_dump(sample_array());'array(6) { ["life"]=> int(42) [123]=> bool(true) [124]=> float(3.1415926535) [125]=> string(3) "Foo" [126]=> string(3) "Bar" [444]=> array(3) { [0]=> int(1) [1]=> int(20) [2]=> int(300) }}这些add_*()函数还可以用于简单对象的内部公共属性. 在第10章"php 4对象"中我们可以看到它们.
小结
你已经花费了一些时间学习了很长的一章, 本章介绍了Zend引擎和php内核中仅次于zval *的通用数据结构. 本章还比较了不同的数据存储机制, 并介绍了很多未来将多次使用的API.
现在你已经有了足够的积累, 可以实现一些相当一部分标准扩展了. 后面的几章将完成剩余的zval数据类型(资源和对象)的学习.
目录上一章: 接受参数下一章: 待续