深入PHP-直观观察array的扩展

皆知PHP的数组是由HashTable和双链表实现的,为了方便大家查看数组的数据结构,开发一个遍历PHP的数组生成Dot描述的PHP插件,生成dot描述以后可以通过一些渲染工具生成图像,本例用的是 Graphviz。

扩展的实现很简单,PHP数组源码是由下面的两种结构体实现的,扩展就是将这两种结构体和各个结构体的关系遍历一遍,生成对应的Dot描述即可。

Java代码  

  1. typedef struct bucket {
  2. ulong h;
  3. uint nKeyLength;
  4. void * pData;
  5. void * pDataPtr;
  6. struct bucket * pListNext;
  7. struct bucket * pListLast;
  8. struct bucket *pNext ;
  9. struct bucket * pLast;
  10. const char *arKey ;
  11. } Bucket;
  12. typedef struct _hashtable {
  13. uint nTableSize;
  14. uint nTableMask;
  15. uint nNumOfElements;
  16. ulong nNextFreeElement;
  17. Bucket *pInternalPointer;
  18. Bucket *pListHead;
  19. Bucket *pListTail;
  20. Bucket **arBuckets;
  21. dtor_func_t pDestructor;
  22. zend_bool persistent;
  23. unsigned char nApplyCount ;
  24. zend_bool bApplyProtection;
  25. } HashTable;

扩展里边函数说明

---------------------------------------------------------------------------------------------

string    dotarray( array $input [, int $flag] )

生成数组数据结构的dot描述

参数

input   需要操作的数组

flag   查看那些数据结构,是扩展提供的3个常量或操作,分别是

DOTARAAY_HASH_TABLE 表示显示HashTable结构

DOTARRAY_DOUBLE_LIST 显示数组的双链表结构

DOTARRAY_CURRENT_POSITION 显示数组现在的内部指针的位置

返回值

成功返回dot描述字符串,错误(非数组等情况)返回false

---------------------------------------------------------------------------------------------

显示双链表结构例子

Java代码  

  1. <?php
  2. $items = array(1,2,8=>‘lalala‘,16=>‘hahaha‘,‘name‘=>‘shiki‘,30=>‘wooooo...‘);
  3. next($items);/*将内部指针移到下一位*/
  4. $result = dotarray($items,DOTARRAY_DOUBLE_LIST|DOTARRAY_CURRENT_POSITION);
  5. echo  $result;

得到的dot描述:

Java代码  

  1. digraph html {label = "Structure of array";
  2. node[shape = record];
  3. ===========部分内容省略============
  4. edge [color=black];
  5. edge [color=green];
  6. sk_array:f5:s -> sk_item_1:f0;
  7. edge [color=black];
  8. }

通过graphviz渲染得到下面的图片

需要解释一下,红色实线为结构中双链表的next指针,红色点线为上一个元素指针。同时提供了DOTARRAY_CURRENT_POSITION标志,出现绿线指向数组内部指针指向key为1的元素(第一个元素key为0)

显示HashTable结构例子

Java代码  

  1. <?php
  2. $items = array(1,2,8=>‘lalala‘,16=>‘hahaha‘,‘name‘=>‘shiki‘,30=>‘wooooo...‘);
  3. next($items);
  4. next($items);
  5. $result = dotarray($items,DOTARAAY_HASH_TABLE|DOTARRAY_CURRENT_POSITION);
  6. echo $result;

生成的结构图片如下:

hash冲突的例子

具体可以参考 PHP hash碰撞拒绝服务漏洞原理http://www.laruence.com/2011/12/29/2412.html,简单介绍即是:Hash表因为”冲突”(碰撞)而退化成链表,如果数据量足够大,
使得php在计算, 查找, 插入的时候, 造成大量的CPU占用, 从而实现拒绝服务攻击。下面是简单的碰撞生成代码:

<

Java代码  

  1. ?php
  2. /*会生出pow(2,$n)个数字*/
  3. $n= 3;
  4. $capacity = pow(2,$n);
  5. $array =array();
  6. for($i=0;$i<$capacity;$i++){
  7. $key = $i<<$n;
  8. $array[$key] =1;
  9. }
  10. $str = dotarray($array,DOTARRAY_DOUBLE_LIST|DOTARAAY_HASH_TABLE);
  11. echo $str,PHP_EOL;

这次将hashtable和双线表同时展示出来,传递的flag为DOTARRAY_DOUBLE_LIST|DOTARAAY_HASH_TABLE,同时展示双链表和HashTable

关于 dot语言 传送门:http://zh.wikipedia.org/wiki/DOT%E8%AF%AD%E8%A8%80

关于 dot渲染工具Graphviz 传送门:http://www.graphviz.org/

扩展源码:https://github.com/Himer/dotarray

时间: 2024-08-28 06:08:43

深入PHP-直观观察array的扩展的相关文章

ExtJS学习-----------Ext.Array,ExtJS对javascript中的Array的扩展

关于ExtJS对javascript中的Array的扩展.能够參考其帮助文档,文档下载地址:http://download.csdn.net/detail/z1137730824/7748893 因为Array中的方法过多.将当中的部分方法设计实例进行学习.实例地址:http://blog.csdn.net/z1137730824/article/details/38797257 (1)Ext.Array中的方法 clean( Array array ) : Array 过滤掉数组里的空值,空值

[C#]Array 添加扩展

众所周知,Array 一旦定义好,譬如四个长度,当需要再往里面添加元素的时候,需要Array.Resize一下才可以,为了提高代码复用,所以索性封装下,方便使用,代码如下: /// <summary> /// Array添加 /// </summary> /// <typeparam name="T">泛型</typeparam> /// <param name="array">Array</para

Array 原型扩展(快速排序,搅乱顺序)

/// 快速快速排序算法Array.prototype.quickSort = function (left, right) { // left = left || 0; // right = right || this.length - 1; if (left < right) { var x = this[right], i = left - 1, temp; for (var j = left; j <= right; j++) { if (this[j] <= x) { i++;

ExtJS学习-----------Ext.Array,ExtJS对javascript中的Array的扩展(实例)

(1)clean var arr = [1,2,null,3,'']; alert(Ext.Array.clean(arr)); //clean的对象:(value === null) || (value === undefined) || (!allowEmptyString ? value === '' : false) || (Ext.isArray(value) && value.length === 0) //结果为1,2,3 (2)difference //difference

JavaScript Array 对象扩展方法

/** 删除数组中指定索引的数据 **/ Array.prototype.deleteAt = function (index) { if (index < 0) { return this; } return this.slice(0, index).concat(this.slice(index + 1, this.length)); } /** 数组洗牌 **/ Array.prototype.random = function () { var tempArr = [], me = th

ES5中新增的Array方法详细说明

ES5中新增的不少东西,了解之对我们写JavaScript会有不少帮助,比如数组这块,我们可能就不需要去有板有眼地for循环了. ES5中新增了写数组方法,如下: forEach (js v1.6) map (js v1.6) filter (js v1.6) some (js v1.6) every (js v1.6) indexOf (js v1.6) lastIndexOf (js v1.6) reduce (js v1.8) reduceRight (js v1.8) 浏览器支持 Ope

Find Minimum in Rotated Sorted Array II -- LeetCode

这道题是Search in Rotated Sorted Array的扩展,思路在Find Minimum in Rotated Sorted Array中已经介绍过了,和Find Minimum in Rotated Sorted Array唯一的区别是这道题目中元素会有重复的情况出现.不过正是因为这个条件的出现,影响到了算法的时间复杂度.原来我们是依靠中间和边缘元素的大小关系,来判断哪一半是不受rotate影响,仍然有序的.而现在因为重复的出现,如果我们遇到中间和边缘相等的情况,我们就无法判

S5中新增的Array方法详细说明

ES5中新增的Array方法详细说明 by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=3220 一.前言-索引 ES5中新增的不少东西,了解之对我们写JavaScript会有不少帮助,比如数组这块,我们可能就不需要去有板有眼地for循环了. ES5中新增了写数组方法,如下: forEach (js v1.6) map (js v1.6) filter (js v1.6

深度理解Key-Value Observing 键值观察

前言   在上一阶段的开发过程中,我们大量使用了 KVO 机制,来确保页面信息的及时同步.也因此碰到了很多问题,促使我们去进一步学习 KVO 的相关机制,再到寻找更好的解决方案.鉴于 KVO 让人欲仙欲死的使用经历,在这里做一个简单分享.此分享的目的,更多的是在于点出 KVO 相关的技术点,供我们大家在学习和使用过程中做一个参考. 对于 KVO 的背后机制感兴趣的同学,可以直接看第三部分,KVC 和 isa-swizzling . 对于 替代方案感兴趣的同学,请直接跳到末尾的第五部分,有列出了目