重庆小潘seo博客

当前位置:首页 > 重庆网站建设 >

重庆网站建设

【问底】王帅:深入PHP内核(三)

时间:2016-08-06 02:13:21 作者:采集侠 来源:网络整理
【导读】王帅在海量分布式Web系统有超过8年沉淀,主导过多个大型系统的架构设计,目前在腾讯企业SaaS团队。 PHP内核系列文章,是作者在PHP领域实践中,把相关原理性的知识,通过更便于理解的方式,系统整理出来分享给读者。希望通过PHP原理性的轻量解读,
0000 0000 0000 0000 0000 & 0 1111 1111 1111 1111 = 0  0001 0000 0000 0000 0000 & 0 1111 1111 1111 1111 = 0 0010 0000 0000 0000 0000 & 0 1111 1111 1111 1111 = 0 。。。

以下这个例子就是这个原理的实现,插入65535个数据需要消耗30秒,而正常情况下仅需要0.01秒。

Inserting 65536 evil elements took 32.726480007172 seconds Inserting 65536 good elements took 0.014460802078247 seconds

文章来源:

4. 操作哈希表的内部函数

PHP的变量符号表是通过哈希表来维护,首先介绍一下再PHP扩展中如何创建一个新的变量。PHP变量介绍,请看我上一篇文章,《深入PHP内核 - 弱类型变量原理探究》。

Bucket的结构:

4)  pDesctructor 哈希表析构的回调函数,当删除一个哈希表的时候,会调用。

免费订阅“CSDN云计算(左)CSDN大数据(右)”微信公众号,实时掌握第一手云中消息,了解最新的大数据进展!


【问底】王帅:深入PHP内核(三)

2. PHP的哈希表实现原理

哈希表的结构:

4)  nNextFreeElement 下一个空元素的地址。

【问底】王帅:深入PHP内核(三)

CSDN发布虚拟化、Docker、OpenStack、CloudStack、数据中心等相关云计算资讯,     分享Hadoop、Spark、NoSQL/NewSQL、HBase、Impala、内存计算、流计算、机器学习和智能算法等相关大数据观点,提供云计算和大数据技术、平台、实践和产业信息等服务。       

哈希函数(Hash Function):将Key通过哈希函数,得到一个指向bucket的指针。MD5,SHA-1是我们在业务中常用的哈希函数。

桶(Bucket):在哈希表中,真正保存数据的容器。

哈希冲突(Hash Collision):两个不同的Key,经过哈希函数,得到同一个bucket的指针。

5) 如果发现新插入元素已经超过HashTable的nTableSize,自动扩容至2倍nTableSize,重新哈希后维护新的HashTable。

5. 哈希冲突(Hashtable Collisions)

因为任何一个哈希表的长度都是有限制的,所以一定会发生键名不同,hash函数计算后得到相同的bucket位置。也就是key1 != key2,但是HASH(key1) = HASH(key2)。如下图2,在发生哈希冲突时(Hash Collision),最坏情况下,所有的键名全部冲突,哈希表会退化成双向链表,操作时间复杂度为O(n)。

键名(Key):在哈希函数转换前,数据的标识。

【导读】王帅在海量分布式Web系统有超过8年沉淀,主导过多个大型系统的架构设计,目前在腾讯企业SaaS团队。

关于作者:王帅,腾讯企业QQ SaaS团队Leader。

9)  persistent 定义了hashtable是否能在多次request中获得持久存在。

6. 哈希碰撞攻击及解决

在去年发现了PHP的哈希碰撞攻击漏洞,PHP5.3.9以下的版本都会受影响。我们在业务压力很重的情况下,还是最短时间内把运营服务器全部更新到5.3.13以上,防止通过PHP的哈希碰撞进行拒绝服务攻击。

【问底】王帅:深入PHP内核(三)

5)  persistent 对应HashTable.persistent,当设置为true的时候,不会在RSHUTDOWN阶段自动销毁。

3) 如果arBuckets[A]不存在,创建新的arBucket[A](INIT_DATA)。或哈希冲突情况下,在arBuckets[A]的链表中找不到Key。创建新的bucket(INIT_DATA),并把新的buckets放在arBucket[A]链表头

我们通过更新哈希表的操作方式,来分析哈希表的操作机制:

3)  pHashFunction 自定义哈希函数的钩子

7)  arBuckets 实际存储Buckets的数组。

《问底》是CSDN云计算频道新建栏目,以实践为本,分享个人对于新时代软件架构与研发的深刻见解。在含有“【问底】”字样标题的文章中,你会看到某个国外IT巨头的架构分享,会看到国内资深工程师对某个技术的实践总结,更会看到一系列关于某个新技术的探索。《问底》邀请对技术具有独特/深刻见解的你一起打造一片只属于技术的天空,详情可邮件至zhonghao@csdn.net。

在分析PHP中HashTable实现原理之前,先介绍一下相关的基本概念:


ZEND_FUNCTION(variable_creation) { zval *new_var1, *new_var2, *new_var3; //创建两个新的变量容器 char *string_contents = "This is a new string variable"; MAKE_STD_ZVAL(new_var1); //为new_var1申请空间并初始化 MAKE_STD_ZVAL(new_var2); ZVAL_LONG(new_var1, 10); //设置new_var1并赋值为long ZVAL_LONG(new_var2, 5); ZVAL_STRINGL(new_var3, string_contents, sizeof(string_contents), 0); //设置new_var3为字符串 ZEND_SET_SYMBOL(EG(active_symbol_table), "local_variable", new_var1); //设置long_variable为函数variable_creation的局部变量 ZEND_SET_SYMBOL(&EG(symbol_table), "global_variable", new_var2); //设置global_variable为全局变量 zend_hash_update( &EG(symbol_table), "new_var3", strlen("new_var3") + 1, &new_var3, sizeof(zval *), NULL ); RETURN_NULL(); }这里的zend_hash_update会更新变量符号表。PHP的数组也是用哈希表来维护,下面通过操作一个array来解释如何使用哈希表来才做数组。