php打印数组-PHP中的链表如何灵活支持多种数据类型?

2023-08-26 0 5,335 百度已收录

大家好,我是公众号“架构改进之路”的作者张章。

在PHP中,数组数据结构的应用处理是非常频繁的。 与Java和C++这些强类型语言相比,PHP字段简直太容易使用了,并且可以存储各种类型的数据。 (如:数字、字符串甚至对象等),这给开发带来了很大的便利。

基于PHP数组的强大功能,我们可以轻松实现更复杂的数据结构,例如栈、队列、列表、集合、字典等。

您是否渴望了解:PHP 是如何实现字段的?

1. PHP字段底层数据结构

PHP数组内部是使用HashTable结构实现的,所以我们先来说说HashTable!

HashTable,也称为散列表,是一种通过键值方式高效访问数据的结构。 哈希表是链表和数组的结合体,它综合了链表快速轮询和链表快速插入的特点。

HashTable主要分为两部分:

1、哈希函数:哈希函数将要查找的值转换为数字索引,通过数字索引可以快速找到该值的位置。

2、哈希碰撞:理想情况下,不同的值经过哈希函数后,结果是不同的; 如果值不相同,则相同的数字将被散列,我们称之为散列冲突。

因此php打印数组,HashTable的应用必然面临哈希冲突的问题。 主要有两种解决方案:链表法和开放寻址法。

在zend_type.h文件中,可以找到HashTable的主要结构定义如下:

zend_array 类型

选取几位主要成员介绍一下:

斗式

Bucket结构比较简单,主要用来存储元素的key和value,以及一个整数h(哈希值,或者说散列值)。

h的值作为最终map元素的存储位置。

2. PHP数组的基本实现

上面的部分我们了解了zend_数组的数据结构,那么我们来看看字段的初始化:

数组的初始化主要是对HashTable成员的设置,初始化时不会立即分配arData的显存,而是在插入第一个元素后才分配arData的显存。

为了更好的理解整个hash结构,我们举个例子来说明一下这个结构:

$data = array(
    'hello' => 'haha',
    1       => 'me to'
    'world' => 'world',
    2       => 2,
);
unset($data[1]);

之前的哈希结构应该是什么样的? 存储在 arData 中的结果应该是什么样的?

画个图例看看吧,比较直观:

arData是Bucket类型的指针,用于专门存储每个元素的key和value,并且按照元素插入的顺序存储数据,因此字段的顺序也由此得到保证。

每个arData字段的元素,从图中可以看出,左边的正数是对hash值取模后的值,它存储了左边arData的索引; 如果-8冲突,则存储数组的头元素。

arData[0]: key='hello', h=xx (具体值), val = 'haha'

arData[1]:val是一个type=IS_UNDEF的zval(取消设置后,并没有立即删除,而是设置为IS_UNDEF)

arData[2]: key='world', h=xx (具体值), val = 'world'

arData[3]: key=NULL, h=2 (可能哈希值冲突), val = 2

....

上面的例子非常具体地解释了nNumUsed、nNumOfElements、arData的含义。

3. PHP数组的有序性

数组中元素的顺序与插入顺序一致。 这是如何实现的?

为了实现PHP数组的有序性,PHP底层哈希表添加了哈希函数与元素链表之间的映射表。 这个映射表也是一个字段,其大小与存储元素的链表相同,存储元素的类型为Integer类型,用于保存元素在实际存储的有序链表中的下标——元素按顺序插入到实际存储的链表中,然后根据哈希函数对链表下标进行哈希处理,存储到新添加的映射表中:

这样就可以完成最终存储数据的排序。

PHP数组的底层结构并没有显式标记这个中间映射表,而是将其与arData放在一起。 链表初始化的时候php打印数组,不仅分配显存用于存储Bucket,还分配相同数量的uint32_t大小的空间,这两块空间一起分配,然后将arData偏移到链表所在的位置存储元素,可以通过arData向前访问这个中间映射表。

总结

PHP 中的字段通过将值映射到键的类型来表征。 与其他语言不同的是,PHP 中链表的键可以是字符串,值可以是任意类型。

除了常规的增删改查之外,对数组还有很多其他的操作,比如复制、合并、销毁、重置等,这些操作对应的代码位于zend_hash.c中,感兴趣的朋友可以去了解一下。

·结尾·

希望明天的讲解对您有所帮助,谢谢!

谢谢阅读!

作者:张章,十年风雨研发,大厂建筑师,《建筑精修之路》专注于建筑技术沉淀、职业生涯和认知升级的学习和分享,坚持分享接地气的干文章,并期待与您一起成长。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 php php打印数组-PHP中的链表如何灵活支持多种数据类型? https://www.wkzy.net/game/162271.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务