2019独角兽企业重金招聘Python工程师标准>>>

如果你想对PHP变量存储结构有一个了解或想对PHP变量加深理解的话,本文是适合你的,比较深入的去看源代码吧。

首先引用laruence关于PHP变量内部存储结构的部分内容(稍作修改)

在PHP中,所有的变量都是用一个结构-zval来保存的, 在Zend/zend.h中我们可以看到zval的定义:

  typedef struct _zval_struct {

    zvalue_value value;

    zend_uint refcount;

    zend_uchar type;

    zend_uchar is_ref;

  } zval;

 

其中zvalue_value是真正保存数据的关键部分,定义为一个联合体(union)

typedef union _zvalue_value {

    longlval;

    doubledval;

    struct {

        char*val;

        intlen;

    } str;

    HashTable *ht;

    zend_object_value obj;

} zvalue_value;

PHP中常见的变量类型有:

1. 整型/浮点/长整型/bool值 等等

2. 字符串

3. 数组/关联数组

4. 对象

5. 资源

 

PHP根据zval中的type字段来储存一个变量的真正类型,然后根据type来选择如何获取zvalue_value的值,比如对于整型和bool值:

   zval.type = IS_LONG;//整形

   zval.type = IS_BOOL;//布尔值

就去取zval.value.lval,对于bool值来说lval∈(0|1);如果是双精度,或者float则会去取zval.value的dval。而如果是字符串,那么:

   zval.type = IS_STRING

这个时候,就会取:zval.value.str而这个也是个结构,存有C分格的字符串和字符串的长度。

而对于数组和对象,则type分别对应IS_ARRAY, IS_OBJECT, 相对应的则分别取zval.value.ht和obj

比较特别的是资源,在PHP中,资源是个很特别的变量,任何不属于PHP内建的变量类型的变量,都会被看作成资源来进行保存,比如,数据库句柄,打开的文件句柄等等。 对于资源:

   type = IS_RESOURCE

这个时候,会去取zval.value.lval, 此时的lval是个整型的指示器, 然后PHP会再根据这个指示器在PHP内建的一个资源列表中查询相对应的资源,此时的lval就好像是对应于资源链表的偏移值。

 ZEND_FETCH_RESOURCE(con, type, zval *, default, resource_name, resource_type);

借用这样的机制,PHP就实现了弱类型,因为对于ZE的来说,它所面对的永远都是同一种类型,那就是zval。

上面部分博文只是阐明了PHP变量的内部表示,要想知道内部表示是如何和用户脚本中的变量联系起来的,需要看laruence的另一篇博文深入理解PHP原理之变量作用域(Scope in PHP),同样引用部分内容(稍作修改)如下:

如果在脚本中写下:

<?php

  $var = "laruence";

  echo $var;

?>

ZE是如何把我的变量var和内部结构zval联系起来的呢?

PHP内部都是使用zval来表示变量的,但是对于上面的脚本,我们的变量是有名字的, var。而zval中并没有相应的字段来体现变量名。PHP内部一定有一个机制,来实现变量名到zval的映射。

在PHP中,所有的变量都会存储在一个数组中(确切的说是hash table)。

当你创建一个变量的时候,PHP会为这个变量分配一个zval,填入相应的变量值,然后将这个变量的名字,和指向这个zval的指针填入一个数组中。然后,当你获取这个变量的时候,PHP会通过查找这个数组,获得对应的zval。

查看_zend_executor_globals结构(这个结构在PHP的执行器保存一些执行相关的上下文信息)

struct _zend_executor_globals {

     ....

    HashTable *active_symbol_table;/*活动符号表*/

    HashTable symbol_table;     /*全局符号表*/

    HashTable included_files;

    jmp_buf *bailout;

    interror_reporting;

     .....

}

 

总结以上两篇博客,对于如下程序

[php] view plaincopyprint?

  1. <?php

  2. class class1

  3. {

  4. public $member;

  5. function __construct()

  6. {

  7. $this->member = 1;

  8. }

  9. }

  10. $a = 1;

  11. $b = 0.56;

  12. $c = "string";

  13. $d = array(1=>1);

  14. $e = new class1;

  15. $f = tmpfile();

  16. debug_zval_dump($a);

  17. debug_zval_dump($b);

  18. debug_zval_dump($c);

  19. debug_zval_dump($d);

  20. debug_zval_dump($e);

  21. debug_zval_dump($f);

  22. ?>

该程序使用debug_zval_dump刺探LONG、DOUBLE、STRING、ARRAY、OBJECT、RESOURCE类型变量,结果如下

[plain] view plaincopyprint?

  1. long(1) refcount(2)

  2. double(0.56) refcount(2)

  3. string(6) "string" refcount(2)

  4. array(1) refcount(2){

  5. [1]=>

  6. long(1) refcount(1)

  7. }

  8. object(class1)#1 (1) refcount(2){

  9. ["member"]=>

  10. long(1) refcount(1)

  11. }

  12. resource(4) of type (stream) refcount(2)

分析绘制整个存储结构如下

对照此图就可以知道PHP各种类型的变量在内存中存储结构和用户变量如何跟内存结构挂钩,了解了这些是下一篇博文关于PHP引用详解的基础。期待下一篇PHP的赋值行为详解吧。

转载于:https://my.oschina.net/jackguo/blog/202400

深入PHP变量存储结构相关推荐

  1. php弱类型机制,浅析php变量存储结构及弱类型实现机制

    根据需要下载相应php源代码: php 下载地址 当前下载php版本为 php-5.5.37 变量的值存储到以下所示zval结构体中. zval结构体定义在Zend/zend_types.h文件 ty ...

  2. php变量结构体的深入理解,第一节 变量的结构和类型

    前言中提到变量的三个基本特性,其中的有一个特性为变量的类型,变量都有特定的类型,如:字符串.数组.对象等等.编程语言的类型系统可以分为强类型和弱类型两种: 强类型语言是一旦某个变量被申明为某个类型的变 ...

  3. 微机原理汇编之部分重要知识整合包括:判断解释程序运行(新手有利)并画存储结构,字节变量,寻址方式

    基本是想到什么说什么,归纳自己遇到的问题 但总的 方向依旧如标题. 一.判断解释程序运行 (建议先看完第二大点–画存储结构) 给出前提代码: 数据段 DATA SEGMENT S DB 1,2,3,4 ...

  4. 《MYSQL是怎样运行的》笔记|配置文件|系统变量|字符集|InnoDB存储结构|数据页结构|索引结构与使用|数据目录|表空间|连表原理|查询优化|BufferPool|事务|redo与undo|锁

    <MYSQL是怎样运行的>笔记 前记: 历时15天,笔记+看书.完成于2022.2.5. 本书是讲具体的数据库实现,而数据库系统概念见:https://blog.csdn.net/qq_4 ...

  5. 数据结构和算法:(3)3.2线性表的链式存储结构

    线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素也就是说你这个可以放在A地点,这个可以放在E地点,A地点和E地点中间可以隔开一个C地点和D地点,这样是允许的),这组存储单元可以存在 ...

  6. 链表list(链式存储结构实现)_VOL.2 如何在python中实现链式存储结构

    一.前言 链式存储作为一种重要的数据存储方式有着极强的数据组织能力.灵活型和动态性,在众多数据结构中应用非常广泛.所谓链式存储结构,就是采用分散的存储空间分别存储每一组数据再通过地址链接的形式将全部数 ...

  7. pytorch默认初始化_小白学PyTorch | 9 tensor数据结构与存储结构

    [机器学习炼丹术]的学习笔记分享<> 小白学PyTorch | 8 实战之MNIST小试牛刀 小白学PyTorch | 7 最新版本torchvision.transforms常用API翻 ...

  8. 图的数组(邻接矩阵)存储结构

    图是比较复杂的数据结构,它由顶点和顶点之间的弧或边组成.任何两个顶点之间都 可能存在弧或边.在计算机存储图时,只要能表示出顶点的个数及每个顶点的特征.每对 顶点之间是否存在弧(边)及弧(边)的特征,就 ...

  9. Oracle物理存储结构--文件

    原文地址:[基础]Oracle物理存储结构--文件作者:诗意方式 1 数据文件 3.查询数据文件参数 要将数据文件置为脱机状态,可以通过下列语句实现,如将SCOTT对象的数据文件置为脱机状态: SQL ...

  10. 链表list(链式存储结构实现)_数据结构知否知否系列之 — 线性表的顺序与链式存储篇(8000 多字长文)...

    从不浪费时间的人,没有工夫抱怨时间不够. -- 杰弗逊 线性表是由 n 个数据元素组成的有限序列,也是最基本.最简单.最常用的一种数据结构. 作者简介:五月君,Nodejs Developer,热爱技 ...

最新文章

  1. perf + 火焰图分析程序性能
  2. 不能成为专业软件测试人员的10大理由
  3. 2015计算机二级java真题_2015年计算机二级《JAVA》章节习题及答案(9)
  4. 任正非致“背叛者”与给竞争对手捐款
  5. client-go入门之2:Job相关操作
  6. 微软的面试题(超变态但是很经典)
  7. 树莓派:3安装NodeJS
  8. mysql 共享表空间存储_MySQL InnoDB共享表空间
  9. stl向量_如何在C ++ STL中将数组元素复制到向量?
  10. offer该怎么选:大公司or小公司?高薪or期权?
  11. qt扫雷鼠标c语言中文网,基于C语言实现的扫雷游戏代码
  12. [转帖]onInterceptTouchEvent和onTouchEvent调用时序
  13. 小松鼠短视频完美开源源码
  14. 3D全息投影 大家可以自己动手制作
  15. macbook m1 打印机不显示打印队列的解决方法
  16. 《电子元器件的可靠性》——第3章可靠性试验
  17. windows xp 安装python3.4.4(xp最高支持到3.4.4,后续版本不支持)
  18. python大数据是什么_python和大数据有什么关系?
  19. mybatis 中文官网
  20. PDF如何裁剪页面,PDF裁剪页面的方法

热门文章

  1. PGM:部分有向模型之条件随机场与链图模型
  2. Java数据类型及类型转换
  3. kindle刷机ttl_求助大神!现在KPW2只能在TTL下进入uboot
  4. 力扣-240 搜索二维矩阵 II
  5. PTA 程序设计天梯赛(21~40题)
  6. 如何给自己的电脑硬盘分区
  7. git本地仓库基本使用(Repository)
  8. KVM(二)CPU 和内存虚拟化
  9. div+css 定位浅析
  10. 不要被C++“自动生成”所蒙骗