php5中最重要的两个结构zval和hashtable的一点总结

php 支持8种基本的数据类型:
    四种标量类型:
    boolean (布尔型)
    integer (整型)
    float (浮点型, 也称作 double)
    string (字符串)
    两种复合类型:
    array (数组)
    object (对象)
    最后是两种特殊类型:
    resource (资源)
    NULL (NULL

无论何种类型都存储在以下结构体+union中:
struct _zval_struct {
	zvalue_value value;	/* 变量的值 */
	zend_uint refcount__gc;
	zend_uchar type;	/* 变量当前的数据类型 */
	zend_uchar is_ref__gc;
};

typedef union _zvalue_value {
	long lval;	/* long value */ //使用long存储int的
	double dval;	/* double value */  //使用double存储float

	struct {
		char *val;
		int len;
	} str;   //使用struct 存储string类型
	HashTable *ht;	/* hash table value */  //存储数组等
	zend_object_value obj;  //对象
} zvalue_value;


直接根据zvalue_value.type就能得到当前php变量的数据类型。

不过一般用下列宏来获取type类型:

#define Z_TYPE(zval)		(zval).type
#define Z_TYPE_P(zval_p)	Z_TYPE(*zval_p)
#define Z_TYPE_PP(zval_pp)	Z_TYPE(**zval_pp)


更详细的关于zval介绍请移步以下链接:

https://github.com/walu/phpbook/blob/master/2.1.md

hash表:

    哈希表在php内部结构几乎无处不在,最常见也是最基本的就是数组类型了

    下面是2个关键struct 哈希表+槽位:

typedef struct _hashtable { 
    uint nTableSize;        // hash Bucket的大小,最小为8,以2x增长。
    uint nTableMask;        // nTableSize-1 , 索引取值的优化
    uint nNumOfElements;    // hash Bucket中当前存在的元素个数,count()函数会直接返回此值 
    ulong nNextFreeElement; // 下一个数字索引的位置
    Bucket *pInternalPointer;   // 当前遍历的指针(foreach比for快的原因之一)
    Bucket *pListHead;          // 存储数组头元素指针
    Bucket *pListTail;          // 存储数组尾元素指针
    Bucket **arBuckets;         // 存储hash数组
    dtor_func_t pDestructor;    // 在删除元素时执行的回调函数,用于资源的释放
    zend_bool persistent;       //指出了Bucket内存分配的方式。如果persisient为TRUE,则使用操作系统本身的内存分配函数为Bucket分配内存,否则使用PHP的内存分配函数。
    unsigned char nApplyCount; // 标记当前hash Bucket被递归访问的次数(防止多次递归)
    zend_bool bApplyProtection;// 标记当前hash桶允许不允许多次访问,不允许时,最多只能递归3次
#if ZEND_DEBUG
    int inconsistent;
#endif
} HashTable;
typedef struct bucket {
    ulong h;            // 对char *key进行hash后的值,或者是用户指定的数字索引值
    uint nKeyLength;    // hash关键字的长度,如果数组索引为数字,此值为0
    void *pData;        // 指向value,一般是用户数据的副本,如果是指针数据,则指向pDataPtr
    void *pDataPtr;     //如果是指针数据,此值会指向真正的value,同时上面pData会指向此值
    struct bucket *pListNext;   // 整个hash表的下一元素
    struct bucket *pListLast;   // 整个哈希表该元素的上一个元素
    struct bucket *pNext;       // 存放在同一个hash Bucket内的下一个元素
    struct bucket *pLast;       // 同一个哈希bucket的上一个元素
    // 保存当前值所对于的key字符串,这个字段只能定义在最后,实现变长结构体
    char arKey[1];       //柔性数组,要兴趣同学可以搜搜


} Bucket;

哈希+双向链表实现php内核中的哈希算法,bucket存储真正的数据 并会存储prev+next bucket的指针和数组中hash的前后指针。详细内容可移步以下链接:

http://www.php-internals.com/book/?p=chapt03/03-01-02-hashtable-in-php


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值