php底层源码之数组
数组key和value的限制条件
<?php
$arr = array(
1 => 'a',
"1" => "b",
1.5 => "c",
true => "d"
);
var_dump($arr); $arr = array(
"foo" => "bar",
"bar" => "foo",
100 => -100,
-100 => 100
);
var_dump($arr);
运行结果:
array (size=1)
1 => string 'd' (length=1)
array (size=4)
'foo' => string 'bar' (length=3)
'bar' => string 'foo' (length=3)
100 => int -100
-100 => int 100
- ·key 可以是integer或者string
- ·value 可以使任意类型。
key会有如下的强制转换:
- ·包含有合法整形值得字符串会被转换为整型
- ·浮点数和布尔值也会被转换为整型
- ·键名null实际会被存储为“”
- ·数组和对象不能被用为键名
- ·相同键名,之前会被覆盖
数组内部实现:
- ·实现数组使用了两个数据结构,一个是HashTable,另一个是bucket。
- ·HashTable结构体用于保存整个数组需要的基本信息。
- ·Bucket结构体用于保存具体的数据内容

HashTable是什么?
哈希表,是根据关键字(key value)而直接访问在内存存储位置的数据结构。也就是说,它通过把键值通过一个函数的计算,映射到保重一个位置来访问记录,这加快了查找速度。使得普通的查找和插入、杀出操作都可以在O(1)的时间内完成。这个映射函数称作哈希函数,存放记录的数组称作哈希表。

HashTable结构体的表示:
typedef struct _hashtable {
uint nTableSize; //hash Bucket的大小,最小为8,以二倍增长
uint nTableMask; //nTableSize-1,索引取值的优化,193491849 & 127
uint nNumOfElements; //hash Bucket中当前存在的元素个数,count()函数会直接返回此值
ulong nNextFreeElement; //下一个数字索引的位置
Bucket *pInternalPointer; //当前遍历的指针,foreach比for快的原因之一,reset,current遍历函数使用
Bucket *pListHead; //存储数组头元素指针
Bucket *pListTail; //存储数组尾元素指针
Bucket **arBuckets; //存储hash数组,实际的存储容器
dtor_func_t pDestructor;
zend_bool persistent;
unsigned char nApplyCount; //标记当前hash bucket被递归访问的次数(防止多次递归)
zend_bool bApplyProtection;
#if ZEND_DEBUG
int inconsistent;
#endif
} HashTable;
Bucket结构体:
typedef struct bucket {
ulong h; //对char *key进行hash后的值,或者使用户指定的数字索引值
uint nKeyLength; //hash关键字的长度,如果数组索引为数字,此值为0
void *pData; //指向value,一般是用户数据的副本,如果是指针数据,则指向pDataPtr
void *pDataPtr; //如果是指针数据,此值会指向真正的value,同时上面pData会指向此值
struct bucket *pListNext; //整个hash表的下一个元素
struct bucket *pListLast; //整个hash表表元素的上一个元素
struct bucket *pNext; //存放在同一个hash Bucket内的下一个元素
struct bucket *pLast; //同一个hash bucket的上一个元素
const char *arKey; //保存当前key所对应的字符串值
} Bucket;
总结成一张图,如下:
php底层源码之数组的更多相关文章
- 为什么很多类甚者底层源码要implements Serializable ?
为什么很多类甚者底层源码要implements Serializable ? 在碰到异常类RuntimeException时,发现Throwable实现了 Serializable,还有我们平进的ja ...
- List-LinkedList、set集合基础增强底层源码分析
List-LinkedList 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 继上一章继续讲解,上章内容: List-ArreyLlist集合基础增强底层源码分析:https:// ...
- List-ArrayList集合基础增强底层源码分析
List集合基础增强底层源码分析 作者:Stanley 罗昊 [转载请注明出处和署名,谢谢!] 集合分为三个系列,分别为:List.set.map List系列 特点:元素有序可重复 有序指的是元素的 ...
- Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap
声明:以下源代码使用的都是基于JDK1.8_112版本 1. ArrayList源码解析 <1. 集合中存放的依然是对象的引用而不是对象本身,且无法放置原生数据类型,我们需要使用原生数据类型的包 ...
- 总结HashSet以及分析部分底层源码
总结HashSet以及分析部分底层源码 1. HashSet继承的抽象类和实现的接口 继承的抽象类:AbstractSet 实现了Set接口 实现了Cloneable接口 实现了Serializabl ...
- LInkedList总结及部分底层源码分析
LInkedList总结及部分底层源码分析 1. LinkedList的实现与继承关系 继承:AbstractSequentialList 抽象类 实现:List 接口 实现:Deque 接口 实现: ...
- Vector总结及部分底层源码分析
Vector总结及部分底层源码分析 1. Vector继承的抽象类和实现的接口 Vector类实现的接口 List接口:里面定义了List集合的基本接口,Vector进行了实现 RandomAcces ...
- Android开发之漫漫长途 Ⅵ——图解Android事件分发机制(深入底层源码)
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...
- 从底层源码浅析Mybatis的SqlSessionFactory初始化过程
目录 搭建源码环境 POM依赖 测试SQL Mybatis全局配置文件 UserMapper接口 UserMapper配置 User实体 Main方法 快速进入Debug跟踪 源码分析准备 源码分析 ...
随机推荐
- dubbo+zookeeper搭建时报错java.lang.NoClassDefFoundError: org/apache/curator/RetryPolicy
说一下我的环境: jdk1.8 dubbo2.6.1 zookeeper3.4.10 maven3.3.9 搭建demo时报错:java.lang.NoClassDefFoundError: org/ ...
- 异步任务神器 和定时任务Celery
异步任务神器 Celery Celery 在程序的运行过程中,我们经常会碰到一些耗时耗资源的操作,为了避免它们阻塞主程序的运行,我们经常会采用多线程或异步任务.比如,在 Web 开发中,对新用户的注册 ...
- Flask上下文源码分析(一)
flask中的上下文分两种,application context和request context,即应用上下文和请求上下文. 从名字上看,可能会有误解,认为应用上下文是一个应用的全局变量,所有请 ...
- 虚拟机VMware安装及Linux系统基础配置(CentOS 7)
PS: 我是 VMware 14 安装 CentOS 7 来配置Linux虚拟机,想要安装 Ubuntu 18.04 的可以自行其他搜或者参考博客:https://blog.csdn.net/gith ...
- Nginx设置黑名单
date: 2019-07-04 14:35:56 author: headsen chen notice: 个人原创 1,在分域名下面设置: [root@pro-nginx:/usr/local/ ...
- yml内容如何转map?
yml内容如何转map 解决方法: Map map = null; Yaml yaml = new Yaml(); File ymlFile = new File("c:/src/tes ...
- Elasticsearch 7.x文档基本操作(CRUD)
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html 1.添加文档 1.1.指定文档ID PUT ...
- python 基础之确认文件是否存在
def check_exist_bills(): file_dir=os.listdir('../db') bills_db_list=[] for item in file_dir: if item ...
- (十五)Centos之安装jdk
一.手动解压JDK的压缩包,然后设置环境变量 1 下载linux版的jdk http://www.oracle.com/technetwork/java/javase/downloads/jdk8-d ...
- 腾讯ios内部视频,什么垃圾视频
前几天朋友在网上花钱买了个,腾讯ios内部视频,我也跟着下载了, 看着这列表,我感觉没什么东西,一看就是基础的东西,完全没有实战的内容,就像培训机构骗学生的东西啊,讲些毛理论,结果一到实战了,问个Sc ...