深入解析PHP的引用计数机制
PHP 深入 解析 机制 引用 计数
2023-06-13 09:15:01 时间
PHP的变量声明并赋值后,变量名存在符号表中,而值和类信息存在zval中,zval中包含四个变量,
struct_zval_struct{
/*Variableinformation*/
zvalue_valuevalue; /*value*/
zend_uintrefcount__gc;
zend_uchartype; /*activetype*/
zend_ucharis_ref__gc;
};
refcount表示value地址与其相同的zval共有多少个,refcount=0时,zval被销毁
is_ref表示一个zval是否被引用,有“0”和“1”两种状态
2.当is_ref=0,且refcount>1时,如果将zval赋值给某个引用变量,那么用来赋值和变量和被赋值的变量会使用同一个原zval,而其他指向原zval的变量将会指向一个新复制的zval,且refcount会被重新计算,例如:$a=1;$b=$a;$c=$a;$d=&$a;,此时ad使用原zval,bc使用新复制出来的zval
3.当is_ref=1,且refcount>1时,如果将zval复制给某个非引用变量,该非引用变量会使用一个新复制的zval,元zval的refcount不变,例如:$a=1;$b=&$a;$c=$a,那么ab使用原zval,而c使用新复制的zval
type表示该zval的值类型,宏定义如下
#defineIS_NULL 0
#defineIS_LONG 1
#defineIS_DOUBLE 2
#defineIS_BOOL 3
#defineIS_ARRAY 4
#defineIS_OBJECT 5
#defineIS_STRING 6
#defineIS_RESOURCE7
#defineIS_CONSTANT8
#defineIS_CONSTANT_ARRAY 9
value表示该zval的值,他也是个共同体,代码如下
typedefunion_zvalue_value{
longlval; /*longvalue*/
doubledval; /*doublevalue*/
struct{
char*val;
intlen;
}str;
HashTable*ht; /*hashtablevalue*/
zend_object_valueobj;
}zvalue_value;
现在你知道php是如何类型变换的了,因为他的值存的其实是个可以代表任何类型的结构体,而具体的取值则根据type来决定是用共同体里的哪个变量来存值的
见下面的例子1
.-----------
$a=1;
$b=$a;
$c=$a;
.-----------
$d=&$a;
.-----------
$a=2;
.-----------
$b=null;
执行完第一部分后来看看输出
1-----------------------------
a:(refcount=3,is_ref=0),int1
b:(refcount=3,is_ref=0),int1
c:(refcount=3,is_ref=0),int1
再看执行完第二部分的
2----------------------------
a:(refcount=2,is_ref=1),int1
b:(refcount=2,is_ref=0),int1
c:(refcount=2,is_ref=0),int1
d:(refcount=2,is_ref=1),int1
注意此时a,d在一起了,他们使用同一个zval,而bc使用一个新生成的zval,同时重新计算两个zval的refcount和is_ref
3----------------------------
a:(refcount=2,is_ref=1),int2
b:(refcount=2,is_ref=0),int1
c:(refcount=2,is_ref=0),int1
d:(refcount=2,is_ref=1),int2
可以知道ad这两个is_ref=1的好基友的值是同时改变的
4----------------------------
a:(refcount=2,is_ref=1),int2
b:(refcount=1,is_ref=0),null
c:(refcount=1,is_ref=0),int1
d:(refcount=2,is_ref=1),int2
bc由于他们的zval的is_ref=0,所以他们不是好基友,他们的值不会同时改变,于是bc的zval再次分裂,b=nullc=1
相关文章
- 【黄啊码】php函数大全,新手必备神器
- 深入PHP:实现MySQL数据库更新(php更新mysql)
- 的关系PHP与Oracle的良好结合(php和oracle)
- 【Linux重启PHP服务的命令指南】(linux重启php命令)
- 深入探索:php与linux 修改细节(phplinux修改)
- 联合MySQL与PHP:双剑合璧(mysql与php)
- Redis实现长连接:PHP开发入门(redis长连接php)
- 环境PHP和MySQL环境搭建:快速、安全、便捷(php和mysql配置)
- 扩展如何在PHP中开启Redis扩展(php开启redis)
- 深入理解MySQL转义在PHP中的应用技巧(mysql转义php)
- Redis在PHP环境下的安装与下载(redis下载 php)
- 深入学习Linux下的PHP编程技巧(linux下php编程)
- Linux下快速搭建PHP开发环境(linux php集成环境)
- 深入Linux:高效部署PHP项目(linux部署php项目)
- PHP实现稳定支持Redis的精彩瞬间(让php支持redis)
- 如何使用Redis技术来优化PHP性能(清楚redis php)
- PHP实现高效的Redis连接(redis连接 php)
- 深入解析php模板技术原理【一】
- PHP和Mysqlweb应用开发核心技术第1部分Php基础-1开始了解php
- PHP得到某段时间区间的时间戳php定时任务
- php读取二进制流(C语言结构体struct数据文件)的深入解析
- PHP设计模式之命令模式的深入解析
- PHP设计模式之调解者模式的深入解析
- 深入解析PHP内存管理之谁动了我的内存
- 深入解析PHP中逗号与点号的区别
- php缓存技术详细总结
- php内核解析:PHP中的哈希表
- php批量删除cookie的简单实现方法