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跟踪 源码分析准备 源码分析 ...
随机推荐
- Java 实例 - instanceof 关键字用法
Java 实例 - instanceof 关键字用法 instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符. instanceof 是 Java 的保留关键 ...
- 2018-2019-2 《网络对抗技术》Exp9 Web安全基础 20165114
Exp9 Web安全基础 目录 一.实验内容 二.基础问题回答 (1)SQL注入攻击原理,如何防御 (2)XSS攻击的原理,如何防御 (3)CSRF攻击原理,如何防御 三.实践过程记录 3.1 注入缺 ...
- fdisk交互
fdisk交互 命令 说明 指令 a 设置可引导标记 toggle a bootable flag b 编辑bsd磁盘标签 edit bsd disklabel c 设置DOS操作系统兼容标记 tog ...
- SQL-W3School-高级:SQL 数据库
ylbtech-SQL-W3School-高级:SQL 数据库 1.返回顶部 1. 现代的 SQL 服务器构建在 RDBMS 之上. DBMS - 数据库管理系统(Database Managemen ...
- osg 加载 fbx文件
#ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include <osg/Group> #include <os ...
- python之socket编程(一)
socket之前我们先来熟悉回忆几个知识点. OSI七层模型 OSI(Open System Interconnection)参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标 ...
- LeetCode_58. Length of Last Word
58. Length of Last Word Easy Given a string s consists of upper/lower-case alphabets and empty space ...
- 基于Docker+Jenkins实现自动化部署
使用码云搭建Git代码存储仓库 https://gitee.com/login 使用码云创建私有私有git仓库 将本地springboot项目上传到git仓库中 基于Docker安装Jenkins环境 ...
- Ubuntu下配置LVS【h】
以后服务器只用CentOS和Ubuntu.下午用redhat装个lvs装了一下午都没搞好,TNND的.果断用Ubuntu,不到两个小时就搞定了. 原文参见: http://kamengwang.blo ...
- Django后台缓存运用,提高并发
图片防盗链 -通过请求头refer控制 -nginx处理 提高网站并发的通用方法 QPS:每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准.衡量一个服务器能抗多大并发的重要 ...