background image

 

23

    zend_uchar is_ref;  

24

}; 

zval 可以看出,PHP 在细节方面的确做了不少优化的功夫。

1.zend_uchar type。采用 uchar 节省内存。
2.zvalue_value value; 采用 union 来替换 void *,这样同样能节省空间,并且比 void *更能表
义清晰。
3.在字符串类型中,默认保留了字符串的长度。这样很容易做到字符串的二进制安全,并且
在计算字符串长度的时候不需要进行扫描。
观察

PHP 弱变量的实现,也会有以下疑惑:

1.为什么会没有 int 类型呢?其实在 PHP 中是有的,只是说默认 int 数据就保存在 long 中。
2.资源类型咋表现的呢?资源在 PHP 内部其实就是一数字。详细后续会介绍。
3.refcount 和 is_ref 是干嘛的呢?呵呵,这就是第二部分要介绍的了。
Reference counting & Copy-on-Write
PHP 和其他语言类似,在其语法中有两种赋值方式:引用赋值和非引用赋值(普通的==赋
值)。
 

25

 

<?php

 

26

    $

a

 = 

1

;  

27

    $

b

 = $a;//非引用赋值  

28

    $

c

 = &$a;//引用赋值  

29

?>

 

引用赋值和非引用赋值在

PHP 内部是如何实现的呢?一种通常的认识是:“引用赋值就是

两个变量对应同一个

Zval,非引用赋值则是直接产生一个新的 zval,同时把对应的值直接

copy 过来。”也就是该代码的内存结构如下:
 

(该图是大
多数人认为

PHP 内

存结构,是

错误的)

这 样的 确能
够 满足 大部
分 情况 下的
需 求, 但显
然 不是 最佳
的解决方案 ,
尤 其是 在内
存 管理 上,
比 如说 以下
代码就会显得非常的低效。

30

<?php

 

31

$

arr

 = 

array

(...);//定义一个非常大的 PHP 数组  

32

myfunc($arr);//每一个函数调用都是一次隐性的非引用赋值