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变量的底层实现)