众所周知,
PHP 与其他脚本语言一样,属于弱变量类型的语言。同时 PHP 本身也是通过 C
语言来实现。本文
主要介绍 PHP 内部是如何实现弱变量类型的,并且据此分析在 PHP 开发
中需要注意的一些使用技术。其中会重点分析
PHP 中的 copy on write 机制和引用相关方面
的话题。
本章节属于《深入 PHP 使用技巧》的第一部分。
如何实现弱变量
在了解
PHP 实现弱变量类型之前,可以先思考下:如何通过 C/C++来实现弱变量类型
的效果呢
?
这个问题我在
BIT 培训课上基本上有两种答案:
方法
1:采用 C++的继承机制。首先定义一个基础类型
Class Var
{
}
然后基于
Var,派生出不同的子类型 IntVar/FloatVar/StringVar 等等。
方法
2:基于 C 语言的 Struct。其中一个字段用于标识类型,另外一个字段用于存储数
据,由于数据要是各种类型,所以通常需要采用指针
比如:
struct var {
Int type;
Void *data;
};
两种思路本身并没有太大区别,也都基本上能够满足需求。在
PHP 中采用了第二种思
路,并且做了比较多的优化。在
PHP 中,所有的变量都会对应同一种类型 zval,其中 zval
也就是
struct _zval_struct,具体定义如下:
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount;
zend_uchar type; /* active type */
zend_uchar is_ref;
};
从
zval 可以看出,PHP 在细节方面的确做了不少优化的功夫。
1.zend_uchar type。采用 uchar 节省内存。
2.zvalue_value value; 采用 union 来替换 void *,这样同样能节省空间,并且比 void *更
能表义清晰。