PHPz2017-05-16 13:19:02
以下论点全部基于
PHP 5
根据php 5.6
的zval
类型(PHP 7
中结构有变化)
typedef struct _zval_struct zval;
...
struct _zval_struct {
/* Variable information */
zvalue_value value; // 值
zend_uint refcount__gc; // 引用计数,默认 1
zend_uchar type; // 变量类型
zend_uchar is_ref__gc; // 是否是引用,默认 0
};
zend_uchar type
的type
的值可以为
IS_NULL
IS_BOOL
IS_LONG
IS_DOUBLE
IS_STRING
IS_ARRAY
IS_OBJECT
IS_RESOURCE
PHP是根据type
来区分变量的类型
所以null
对php
来说,与bool
/long
对比, 并没有什么特殊的优势
null
变量,表示zvalue_value value
无需赋值,相比String
、Array
需要申请大量内存的操作来说,还是具备一定的优势,但是对比LONG
、BOOL
来说,这点性能优势基本可以忽略,解释如下:
小到一个bool值,大到一个复合数组,在php
核心实现中,都是C语言的zVal结构
。
归纳起来,也就是如下PHP声明:
$n = null;
$a = true;
$b = 123;
$c = 321.123;
$d = 'string';
$e = [];
$f = new SomeClass();
$g = fopen('xxx', 'r');
$h = &$b; //引用,比较特殊
以上变量,在/usr/bin/php
执行到这行时,都会在内存中转化为zVal结构
,/usr/bin/php
执行到这行时,都会在内存中转化为zVal结构
,type
的值上面已经讲解过,下面讲解其值将如何存储,
zvalue_value value
的结构PHP变量的值存储在zvalue_value value
变量中,其中zvalue_value
变量中,其中zvalue_value
的结构如下:
typedef union _zvalue_value {
long lval; //整形
double dval; //浮点
struct { //字符串
char *val;
int len;
} str;
HashTable *ht; //数组, 也就是hashmap
zend_object_value obj; // Object
} zvalue_value;
union
在C语言里面是一个联合体
,表示一次只会一个成员生效,其特点是内存的长度=最长的那个成员长度。
PHP变量使用的成员如下:
NULL 不使用
BOOL/LONG 使用 lval;
DOUBLE 使用 dval;
String 使用 str;
Array 使用 ht;
Resource 使用 lval;
Object 使用 obj;
其中
Object
、Resource
、Array
的实现会非常复杂,不在本文讨论之列,详情请查看文本底部的超级链接。
根据上表,NULL
类型的变量在设置type = IS_NULL
之后,而无需赋值value
NULL
类型的变量在设置type = IS_NULL
之后,而无需赋值value
而0/false
赋值在设置type = IS_BOOL / IS_LONG
之后,再多一句赋值value.lval = 0;
而0/false
赋值在设置type = IS_BOOL / IS_LONG
之后,再多一句赋值value.lval = 0;
的操作:
然而不论value
中的成员
是否赋值,value
中的成员
是否赋值,zvalue_value value
都是需要占用内存的,
如此而来,NULL
仅仅是少一个赋值 4 bytes
内存 的过程,但是以现代的CPU来看,这点优势可以忽略不计。
具体请看http://www.php-internals.com/...