PHPZend引擎如何存储变量

  当我们在使用PHP定义一个变量时,不需要指定变量类型,并且还可以随意改变变量类型。不免产生疑问,PHP底层的C语言是如何实现的呢?
  当我们定义a=1时,源码参考:https://github.com/php/php-src/blob/PHP-5.6.40/Zend/zend.h

$a = 1;

  变量名a会存储到全局符号表symbol_table中,符号表的值指向结构体的内存地址,变量的值1存储在这个结构体中

struct _zval_struct {
	zvalue_value value;		/* 指向_zvalue_value */
	zend_uint refcount__gc; /*变量被指向次数,这里是1*/
	zend_uchar type;	/* IS_LONG */
	zend_uchar is_ref__gc;
};
typedef union _zvalue_value {
	long lval;					/* 1 */
	double dval;
	struct {
		char *val;
		int len;
	} str;
	HashTable *ht;
	zend_object_value obj;
	zend_ast *ast;
} zvalue_value;

  _zval_struct结构体中的type一共有八种类型:IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_ARRAY、IS_OBJECT、IS_RESPURCE。Zend文件定义如下:

/* data types */
/* All data types <= IS_BOOL have their constructor/destructors skipped */
#define IS_NULL		0
#define IS_LONG		1
#define IS_DOUBLE	2
#define IS_BOOL		3
#define IS_ARRAY	4
#define IS_OBJECT	5
#define IS_STRING	6
#define IS_RESOURCE	7
#define IS_CONSTANT	8
#define IS_CONSTANT_AST	9
#define IS_CALLABLE	10

  当把变量a赋值给变量b时

$a = 1;
$b = $a;

  符号表新增变量名b,值为上面_zval_struct结构体的内存地址,也就是说并不会产生新的结构体。而是将原有结构体的refcount_gc+1,形成以下结构

{
    union zvalue {long 1} 
    type: is_LONG 
    refcount_gc:2
    is_ref_gc:0
}

在这里插入图片描述

  当在对修改变量b的值时,就会产生新的结构体,符号表里面b对应的内存地址更新为新的结构体地址。这种只有在改变b的值的时候才会产生新的结构体称为copy on write,在其它语言中也有相似应用。

$a = 1;
$b = $a;
$b = 2;
a{
    union zvalue {long 1} 
    type: is_LONG 
    refcount_gc:1
    is_ref_gc:0
}
b{
    union zvalue {long 2} 
    type: is_LONG 
    refcount_gc:1
    is_ref_gc:0
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值