您现在的位置是:群英 > 开发技术 > PHP语言
php8底层内核源码之三,数组是什么?
Admin发表于 2022-07-23 17:46:54578 次浏览
这篇文章主要给大家介绍“php8底层内核源码之三,数组是什么?”的相关知识,下文通过实际案例向大家展示操作过程,内容简单清晰,易于学习,有这方面学习需要的朋友可以参考,希望这篇“php8底层内核源码之三,数组是什么?”文章能对大家有所帮助。


本篇文章给大家介绍《解析PHP8底层内核源码-数组(三)》。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

相关文章推荐:《解析PHP8底层内核源码-数组(一)》《解析PHP8底层内核源码-数组(二) 》《解析PHP8底层内核源码-数组(四)》

上文已经全文剖析了PHP中数组的基本结构实现和 索引的组成原理

依赖于 _Bucket 和 _zend_array 两个结构体

通过散列函数实现o(1)的复杂度

可是bucket之前还有一个 索引数组 我当时在理解这个索引数组的时候走了不少坑

下图为 $c =array('x'=>1,'y'=>2,'z'=>3,'a'=>0); 中数组c的bucket结构

上文已经说了 如果是packed_array的时候 索引数组一直是2 也不会发挥作用

因为如果是packed key直接是null 也不需要去计算hash值 这个索引数组只是用于快速定位h值所用

$a =array(1,2,3) 的 bucket
typedef struct _Bucket {
zval              val;   //数组的值 ( 复习下 zval只有16个字节)
zend_ulong         h;     // key的 h  值
zend_string      *key;      //当数组为 hash_array时候 会用到 也就是 key的值  
} Bucket;

当为packedarray的时候 也不要被val影响了你的学习思路 h值就等于 数组的位置的下标(数组都是从0开始 ,所以下标也从0开始)。比如上文提到的
$b =array(1=>'a',3=>'b',5=>'c'); 其中数组b 一样也是packed_array 结构如下

因为数组b没有定义第0个数组的值 所以 是无效的 其中$b[1]内容是‘a’ 这里我图上是直接标出了val=a(zval) 其实 是16字节的zval中 类型为 string的 zend_string 这里面又套了之前学到的gc 等 所有PHP内核源码里存在很多无限套娃 方便你温故知新。

返回来再说 $c =array('x'=>1,'y'=>2,'z'=>3,'a'=>0);

结构如下

这个h值很大 是用key 通过time33计算得来的哈希值 我也不知道为什么叫哈希值 我觉得就是通过time33计算得来的h值 然后形成散列表

散列表主要由两部分组成:存储元素数组、散列函数。一个简单的散列函数可以采用取余数的方式,比如 散列表大小为8 那么在散列表初始化数组的时候就分配8个元素大小的空间,跟进key的hash code 除以8 得到的值就是该元素在数组中的下标。这样就可以通过key映射到存储数组中的具体位置

但是直接用上面的方式实现数组 会有一个问题 :元素在数组中位置是随机的 它是无序的

PHP中的数组是有序的 所以它在散列函数与元素数组之间加了一层索引表 这个索引表也是一个数组。大小与存储元素的数组相同。但是它存储的元素类型永远都是整型,用于保存元素数组在实际存储的数组中的下标:元素按照先后顺序依次插入实际存储数组中 ,然后将其数组下标按照散列函数计算出的位置存储在新加的索引标中。

第一步计算出来 4 然后 取索引表中 找到-4 因为这是第0个数组所以把索引表中第-4个数组里面的值设置为0 然后把真正的数组表中第0个元素设置为真正赋值的zval

散列表中不同元素的key 可能最后计算得到的哈希值 是一样的 也就是指向同一个索引表中的下标 这个时候就会发生hash冲突 。因为索引表只能存一个元素 PHP为了实现hash冲突 采用了拉链法 就是把值用链表拉起来 。可以参考下图 《PHP7 内核剖析-秦朋》

正常情况 val.u2.next 的值为-1 也就是初始值 一旦出现hash冲突 那么这里的值就会指向 冲突之前的数组的真实位置 。


以上就是关于“php8底层内核源码之三,数组是什么?”的相关知识,感谢各位的阅读,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注群英网络,小编每天都会为大家更新不同的知识。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

标签: php8
相关信息推荐
2022-01-12 18:08:26 
摘要:PHP怎么实现数值转ASCII?实现这一需求并不难,我们利用NumToASCII()就能将数值转字母,下面我们来看看具体怎样实现,文中有示例供大家参考,需要的朋友可以看一看。
2022-01-11 18:40:52 
摘要:调试python路径无效的问题如何解决?有一些朋友有遇到在调试设置时,出现python路径无效的问题,但是不知该如何解决。对此这篇就给大家来分享一下解决方法,具体的操作步骤如下,有需要的朋友可以参考。
2022-08-27 17:49:18 
摘要:转换为日期格式的方法:1、使用“strtotime($string)”语句,将指定字符串类型的日期时间文本转为时间戳;2、使用“date("Y-m-d H:i:s",时间戳)”语句格式化时间戳,将其转为“年-月-日 时:分:秒”的日期格式。
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部