php 变量实现原理,php底层原理之变量(一)

搜索热词

上次跟大家讲了垃圾回收机制后,有些小伙伴对底层原理比较感兴趣,私信问我了一些关于变量的相关知识,既然大家对变量比较感兴趣,那么这次我们来系统的讲一下变量的底层原理

变量结构

首先,我们还是先摆上我们的zval结构体,即PHP所有变量都会以zval结构体的形式实现

次数,为0删除该变量

zend_uchar type; //变量类型

zend_uchar is_ref__gc; //区分是否是引用变量,是引用为1,否则为0

};

从上面结构体内容可以看出每一个PHP变量都会由变量类型、value值、引用计数次数和是否是引用变量四部分组成

注:上面zval结构体是PHP5.3版本之后,PHP7版本之前的结构

变量类型

看到这里,可能会有小伙伴们问我,PHP不是有8种数据类型吗?但是为什么对应的zvalue的value值只有5种?

原因是这样的,PHP出于对内存节省的考虑,所以对于一些变量类型做了复用,并没有一一对应去定义每个变量类型

下面我们看一下zvalue的每个value值所对应的变量类型

整型、布尔型、资源

zval.value.dval => 浮点型

zval.value.str => 字符串

zval.value.*ht => 数组

zval.value.obj => 对象

看到这里大家可能会比较奇怪,布尔型和资源是怎么对应到zval.value的lval上的呢?还有,NULL呢?

布尔型:

就像我们会将true和false映射成0和1进行数据库存储一样,PHP也是这么做的。所以PHP发现zval的type值是布尔型时,会将布尔型转成0或1存储在zval.value的lval中

资源:

资源对于PHP来说属于一个比较特殊的变量,而PHP会将每个资源对应的资源标识存储在zval.value的lval中。常见的资源有:文件句柄、数据库句柄等

NULL:

对于NULL来说,就更好理解了,因为本身通过zval的type值即可区分,所以并没有将NULL值存储在zval的value中

变量生成

PHP作为一门动态语言,没有先声明变量后赋值的习惯,所以都是拿来一个变量直接就进行了赋值,那么是如何实现的呢?

举例:

PHP">$name = "许铮的技术成长之路";

变量容器生成

其实每次变量被常量赋值时,都会对应生成一个变量容器。刚才的例子会生成一个变量容器,容器的type是字符串类型,而value值则是许铮的技术成长之路,且此时该变量容器的ref_count会加1

变量名和变量容器关联

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

变量作用域

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

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

变量销毁

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

1、手动销毁

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

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

而对于垃圾回收机制的销毁,如果你不了解其相关原理,那么我建议你看下我之前写的文章PHP底层原理之垃圾回收机制

思考

今天,我们从底层的角度,将变量从生成到销毁讲了一遍。对于变量的生成,我们是拿常量赋值作为示例讲解的,那么变量之间的赋值呢?是什么原理呢?且听下回分解~

总结

以上是编程之家为你收集整理的php底层原理之变量(一)全部内容,希望文章能够帮你解决php底层原理之变量(一)所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

你可能感兴趣的:(php,变量实现原理)