搜索
首页后端开发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结构

4a167edc4a1a3e15753be51c8808d70.png

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

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

224e6328afdb6438b0ae2aa8d7726be.png
$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  结构如下

3cd34252d7729f5f230e5a3a5027106.png

因为数组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);

结构如下

021be407f0bf388d14f1fb765a32d92.png

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

0ef5476843285bb71393ffaf965d777.png

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

499a6c30bd075efe1b957822d32e96a.png

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

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

5c9f67f91d7a5d3eccb667e16842d7a.png

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

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

0d97a77d9d7bce4216fca1176b53034.png

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

▏本文经原作者PHP崔雪峰同意,发布在php中文网,原文地址:https://zhuanlan.zhihu.com/p/360952022

以上是解析PHP8底层内核源码-数组(三)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:PHP崔雪峰。如有侵权,请联系admin@php.cn删除

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。