PHP变量的底层实现

PHP变量是通过zval结构体来存储的,如下:


php5.3版本之后,php7版本之前的结构

type字段的值为以下常量:

IS_NULL,IS_BOOL,IS_LONG,IS_DOUBLE,IS_STRING,IS_ARRAY,IS_OBJECT,IS_RESOURCE

其中,变量类型包含:

1、整型/浮点/长整型/bool值

2、字符串

3、数组/关联数组

4、对象

5、资源

PHP中有8种数据类型,为什么zval->value 联合体中,只有5种?

1、NULL,直接 zval->type = IS_NULL,就可以表示,不必设置 value的值.

2、BOOL型 , zval->type = IS_BOOL, 再设置 zval.value.lval = 1/0;

3、Resource型 ,资源型 往往是服务器上打开的一个接口,如果 文件读取接口.zval->type = IS_RESOURCE, zval->tyoe.lval = 服务器上打开的接口的编号

变量容器生成

举例:

$a = '测试字符串';

其实每次变量被常量赋值时,都会对应生成一个变量容器,上边的例子会生成一个变量容器,容器的type是字符串类型,而value值则是'测试字符串',且此时该变量容器的ref_count会加1

变量名和变量容器关联

而变量name是如何与变量容器关联起来的呢?其实也是使用了php的一个内部机制,即哈希表。每个变量的变量名和指向zval结构的指针被存储在哈希表内,以此实现了变量名到变量容器的映射

变量作用域

上面我们提到了变量名和变量容器映射的概念。对于php来说,变量有全局变量和局部变量之分;那么,他们都是存储到一个哈希表内了么?

其实不是的,变量存储也有作用域的概念。全局变量被存储到了全局符号表内,而局部变量也就是指函数或对象内的变量,则被存储到了活动符号表内(每个函数或对象都单独维护了自己的活动符号表。活动符号表的生命周期,从函数或对象被调用时开始,到调用完成时结束)

变量销毁

变量销毁,分为以下几种情况:

1、手动销毁

2、垃圾回收机制销毁(引用计数清0销毁和根缓冲区满后销毁)

我们这次主要讲一下手动销毁,即unset,每次销毁时都会将符号表内的变量名和对应的zval结构进行销毁,并将对应的内存归还到php所维护的内存池内(按内存大小划分到对应内存列表中)

垃圾回收机制-待完善

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 今天听到别人问php的变量内存是怎么管理的,这个我之前还真没研究过,后来找到一些资料,似乎明白了,这里写出来,希望...
    信仰与初衷阅读 913评论 1 1
  • 1.有人说 今天写着写着代码用到了unset所以想整理一下. 有的人说PHP的unset并不真正释放内存, 有的说...
    会长__阅读 1,068评论 0 5
  • 每一种语言都有自己的自动垃圾回收机制,让程序员不必过分关心程序内存分配,但是在OOP中,有些对象需要显式的销毁;防...
    文档随手记阅读 4,822评论 2 3
  • 前段时间出差去青岛,顺便去了趟山东科技大学,回想自己自2005年毕业参加工作已经有14个年头了,时光荏苒,岁月如梭...
    翟龙宝阅读 463评论 0 3
  • 领导责任有时是一项沉重的负担,也是迫切和重要的挑战。在灰色区域,你的任务不是找到解决方案,而是依靠自己的判断力,创...
    sageness阅读 108评论 0 0