fantom

一、php变量基本特性

1、名称,变量的标示符。比如姓名标示符

2、类型   变量的类型   比如男还是女

3、值内容  具体内容    比如爱好等

二、php类型

1、php是弱类型

2、分为三类

  (1)、标量类型:boolean, integer, float(double)

     (2)、复合类型:array,object

     (3)、特殊类型: resource, NULL

三、变量存储结构

一、变量结构

struct _zval_struct {

    zvalue_value value; //存储变量的值

    zend_uint refcount__gc: //引用计数,5-3之前为refcount

    zend_uchar type;//变量具体的类型,IS_NULL, IS_BOOL, IS_LONG,IS_DOUBLE, IS_STRING,IS_ARRAY,IS_RESOURCE.

   zend_uchar is_ref__gc; //是否为引用, 5-3之前为ref

}

 

二、变量值存储

1、使用联合体而不使用结构体,空间利用率的考虑,因为一个变量只是属于一中类型。

typedef union _zvalue_value {

   long lval;

  double dval;

  struct { //C字符串以\0结尾,多存储一个长度,空间换时间

    char *val;

    int len;

 }str;

    HashTable *ht;  数据array, php哈希表实现二个数据结构HashTable 和Bucket,复杂度为o(n)

    zend_object_value obj;

}zvalue_value;

2、对象Object 包括类的属性,和方法等数据

typedef struct _zend_object_value{

    zend_object_handle handle; //EG(object_store).object_buckets 索引  unsigned int 类型

    zend_object_handles *handles; //将对象进行操作时的处理函数保存。

}

 三、哈希表(HashTable)

1、哈希表是一种通过哈希函数,将特定的键映射到特定值的一种数据结构,它维护键和值之间的对应关系。通常复杂度为O(1),哈希表为数组的扩展或者关联数组。实现文件zend/zend_hash.h 和zend/zend_hash.c

2、键(key):用户操作数据的标示,例如php数组中的索引,或者字符串键等。

3、槽(slot/bucket): 哈希表中用于保存数据的一个单元,存放的容器。

4、哈希函数(hash fuction): 将key映射(map)到数据应该存放的slot所在的位置的函数。

5、哈希冲突(hash collision):哈希函数将不同的Key映射到同一个索引的情况。

     冲突解决方法:

            链接法

             【1】、多个KEY映射到一个槽时, 哈希表退化成一个链表,复杂度为0(n),php中的HashTable的哈希冲突就是链接法。

      php的bucket实现中采用双向链表,具体结构如下:

                typedef struct bucket {

                ulong h;   // 对char *key进行hash后的值,或者是数字的索引值

                uint nKeyLength; // hash关键字长度,如果索引为数字,那么这个值为0

                void *pData;   // 指向用户数据(其实是数据副本,在做UPDATE_DATA或者INIT_DATA时分配了新的空间,将用户数据拷贝了一份),如果是一个指针,那么指向下面的pDataPtr

                void *pDataPtr; // 如果是指针数据,那么这个值指向真正的用户数据(同上一个,也是用户数据的副本),同时上面的pData指向该值。

                struct bucket *pListNext; // 指向整个hash表的下一个元素

                struct bucket *pListLast; // 指向整个hash表的上一个元素

                struct bucket *pNext;  // 指向同一个Bucket内的下一个元素

                struct bucket *pLast;  // 指向同一个Bucket内的上一个元素

                char arKey[1];

                } Bucket;  

 

           开放寻址法

             【1】、发生冲突,继续寻找下一个槽,直到找到没被占用的槽。插入和查询都是同一策略。

 6、哈希表实现

    【1】、实现哈希函数

    【2】、冲突的解决

    【3】、操作接口的实现

7、哈希表示意图

 

分类:

技术点:

相关文章: