上一小节介绍了引用计数,多个变量可能指向同一个value,然后通过refcount统计引用数,这时候如果其中一个变量试图更改value的内容则会重新拷贝一份value修改,同时断开旧的指向,写时复制的机制在计算机系统中有非常广的应用,它只有在必要的时候(写)才会发生硬拷贝,可以很好的提高效率,下面从示例看下:
$a = array(1,2);
$b = &$a;
$c = $a;
//发生分离
$b[] = 3;
最终的结果:
不是所有类型都可以copy的,比如对象、资源,实时上只有string、array两种支持,与引用计数相同,也是通过zval.u1.type_flag
标识value是否可复制的:
#define IS_TYPE_COPYABLE (1<<4)
| type | copyable |
+----------------+------------+
|simple types | |
|string | Y |
|interned string | |
|array | Y |
|immutable array | |
|object | |
|resource | |
|reference | |
copyable 的意思是当value发生duplication时是否需要或者能够copy,这个具体有两种情形下会发生:
$a = [];
实际会有两个数组,而$a = "hi~";//interned string
则只有一个string$a = [];$b = $a; $b[] = 1;
这里会分离,类型是array所以可以复制,如果是对象:$a = new user;$b = $a;$a->name = "dd";
这种情况是不会复制object的,$a、$b指向的对象还是同一个具体literal、局部变量区变量的初始化、赋值后面编译、执行两篇文章会具体分析,这里知道变量有个copyable
的属性就行了。