Home >Backend Development >PHP Tutorial >深入PHP-直观观测array的扩展

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

WBOY
WBOYOriginal
2016-06-13 12:17:191059browse

深入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.   
  13. typedef struct _hashtable {  
  14.      uint nTableSize;  
  15.      uint nTableMask;  
  16.      uint nNumOfElements;  
  17.      ulong nNextFreeElement;  
  18.      Bucket *pInternalPointer;      
  19.      Bucket *pListHead;  
  20.      Bucket *pListTail;  
  21.      Bucket **arBuckets;  
  22.      dtor_func_t pDestructor;  
  23.      zend_bool persistent;  
  24.      unsigned char nApplyCount ;  
  25.      zend_bool bApplyProtection;  
  26. } HashTable;  
  27.    



扩展里边函数说明 
--------------------------------------------------------------------------------------------- 
string    dotarray( array $input [, int $flag] ) 
生成数组数据结构的dot描述 
参数 
input   需要操作的数组 
flag   查看那些数据结构,是扩展提供的3个常量或操作,分别是 
     DOTARAAY_HASH_TABLE 表示显示HashTable结构 
     DOTARRAY_DOUBLE_LIST 显示数组的双链表结构 
     DOTARRAY_CURRENT_POSITION 显示数组现在的内部指针的位置 
返回值 
成功返回dot描述字符串,错误(非数组等情况)返回false 
--------------------------------------------------------------------------------------------- 
显示双链表结构例子 

Java代码  收藏代码
  1.   
  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.   
  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.   
  3. /*会生出pow(2,$n)个数字*/  
  4. $n= 3;  
  5. $capacity = pow(2,$n);  
  6. $array =array();  
  7. for($i=0;$i
  8.     $key = $i
  9.     $array[$key] =1;  
  10. }  
  11.   
  12.   
  13. $str = dotarray($array,DOTARRAY_DOUBLE_LIST|DOTARAAY_HASH_TABLE);  
  14. 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

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn