这篇文章我尽量用通俗的话来稍微形容一下两者zval的不同。总结在最后。
正式开始
zval的结构:
- 类型
- 值
- refcount:指此参数被用了几次(包括引用),垃圾回收机制也是判断这个值,int
- is_ref:是否被引用,true|false
<?php
$a = 1;
xdebug_debug_zval('a');
?>
在PHP5下会打印:
a: (refcount=1, is_ref=0)=1
PHP7:
a: (refcount=0, is_ref=0)int 1
这个例子我们可以看出来PHP7对于int类型1,不做计数。我们可以查阅到这是zval的其中一个改动。
PHP5标量数据类型会计数,PHP7标量数据类型(布尔,整形,字符串,浮点型)不再计数,不需要单独分配内存。
<?php
$a = "new string";
xdebug_debug_zval('a');
?>
PHP5:
a: (refcount=1, is_ref=0)='new string'
PHP7:
a: (refcount=1, is_ref=0)string 'new string' (length=10)
<?php
$a = "new string";
$b = $a;
xdebug_debug_zval( 'a' );
?>
PHP5:
a: (refcount=2, is_ref=0)='new string'
PHP7:
a: (refcount=1, is_ref=0)string 'new string' (length=10)
这边会发现PHP7下重复赋值之后,计数count没有+1。
因为字符串也是属于标量,不再多次记录。
<?php
$a = "new string";
$c = $b = $a;
xdebug_debug_zval( 'a' );
unset( $a, $b );
xdebug_debug_zval( 'c' );
?>
PHP5:
a: (refcount=3, is_ref=0)='new string'
c: (refcount=1, is_ref=0)='new string'
PHP7:
a: (refcount=1, is_ref=0)string 'new string' (length=10)
c: (refcount=1, is_ref=0)string 'new string' (length=10)
这里unset($a)之后,就会把变量c复制分离出来。
<?php
$a = array( 'meaning