background image

PHP 原理之变量分离 引用(Variables Separation)

以下一览

PHP 工程师就为大家介绍一下 PHP 中变量分离和引用的概念。需要的朋友可以过

来参考下
首先我们回顾一下

zval 的结构:

代码如下

:

 
struct _zval_struct {

        

/* Variable information */

        

zvalue_value value; 

/* value */

        

zend_uint refcount;

        

zend_uchar type; 

/* active type */

        

zend_uchar is_ref;

};
 
其中的

refcount 和 is_ref 字段我们一直都没有介绍过,我们知道 PHP 是一个长时间运行的

服务器端的脚本解释器。那么对于它来说,效率和资源占用率是一个很重要的衡量标准,也
就是说,

PHP 必须尽量介绍内存占用率,考虑下面这段代码:

代码如下

:

 
<?php

   

$

var

 = "laruence";

   

$var_dup = $

var

;

   

unset($

var

);

?>
 
第一行代码创建了一个字符串变量,申请了一个大小为

9 字节的内存,保存了字符

”laruence”和一个 NULL(/0)的结尾。

第二行定义了一个新的字符串变量,并将变量

var

的值

”复制”给这个新的变量。

第三行

unset 了变量

var

这样的代码在我们平时的脚本中是很常见的,如果

PHP 对于每一个变量赋值都重新分配内

存,

copy 数据的话,那么上面的这段代码公要申请 18 个字节的内存空间,而我们也很容易

的看出来,上面的代码其实根本没有必要申请俩份空间,呵呵,

PHP 的开发者也看出来了:

我们之前讲过,

PHP 中的变量是用一个存储在 symbol_table 中的符号名,对应一个 zval 来

实现的,比如对于上面的第一行代码,会在

symbol_table 中存储一个值”

var

”, 对应的有一个

指针指向一个

zval 结构,变量值”laruence”保存在这个 zval 中,所以不难想象,对于上面的

代码来说,我们完全可以让

var

”和”var_dup”对应的指针都指向同一个 zval 就可以了。

PHP 也是这样做的,这个时候就需要介绍我们之前一直没有介绍过的 zval 结构中的
refcount 字段了。
refcount,顾名思义,记录了当前的 zval 被引用的计数。
比如对于代码

: