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跟踪 源码分析准备 源码分析 ...
随机推荐
- kill 一个名字 程序的所有进程
ps aux | grep chrome | awk '{print $2}' | xargs kill -9
- oracle 编译无效对象
在数据库中,会存在一些无效的对象,导致这种现象的发生原因很多,其中最常见的就是数据库升级(例如修改了表的结构),迁移而引起. 编译无效对象的方式: 1 使用alter **** compile 语句进 ...
- java 抽象类为什么不能被实例化?
我把CSDN论坛里面的一个帖子内容list到下面,自己看着理解,东家一言,西家一语,杂合起来,基本上也就理解了java中的抽象类为什么不能被实例化了. 因篇幅有限,只能罗列部分留言 以下内容不分先后顺 ...
- 简易的CRM系统案例之Struts2+JSP+MySQL版本
对简易的CRM系统案例之Servlet+Jsp+MySQL版本改进 Servlet优化为Struts2 学习 <?xml version="1.0" encoding=&qu ...
- IDEA 不编译java以外的文件
解决办法:修改pom 文件 <build> <resources> <resource> <directory>src/main/java</di ...
- MySQL复制线程状态转变
一.主库线程状态(State)值 以下列表显示了主从复制中主服务器的Binlog Dump线程的State列中可能看到的最常见状态(SHOW PROCESSLIST).如果Binlog Dump线程在 ...
- 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_01-用户认证需求分析
1.1 用户认证与授权 截至目前,项目已经完成了在线学习功能,用户通过在线学习页面点播视频进行学习.如何去记录学生的学习过程 呢?要想掌握学生的学习情况就需要知道用户的身份信息,记录哪个用户在什么时间 ...
- ElasticSearch——冷热(hot&warm)架构部署
背景 最近在做订单数据存储到ElasticSearch,考虑到数据量比较大,采用冷热架构来存储,每月建立一个新索引,数据先写入到热索引,通过工具将3个月后的索引自动迁移到冷节点上. ElasticSe ...
- php判断进程是否存在
//计划任务定时检测master进程是否存在,不存在则启动,以root用户运行 public function checkMaster() { $cmd = 'ps axu|grep "Uc ...
- Python3之多重继承
继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能. Animal类层次的设计,假设我们要实现以下4中动物 Dog-狗狗 Bat-蝙蝠 Parrot-鹦鹉 Ostrich-鸵鸟 ...