<?php $a = 1; xdebug_debug_zval('a'); $b = $a; xdebug_debug_zval('a'); $a = 2; xdebug_debug_zval('a'); xdebug_debug_zval('b');
结果以下:php
a: (refcount=1, is_ref=0)=1 a: (refcount=2, is_ref=0)=1 b: (refcount=1, is_ref=0)=2 a: (refcount=1, is_ref=0)=1
过程分析: bash
1,$a 建立了 引用计数(指向数)为1,非地址引用 而且 值为int类型 1 的 zval容器;
2,新建一个$b,因为是经过赋值的方式将 $a 赋值给 变量$b 的,两个变量所保存的值彻底同样,所以不会申请新内存来存放新变量所保存的值,而是简单的经过一个计数器来共用内存。因此,此时$b也指向 $a 的zval 容器,能够看到引用计数变为了2,仍然是非地址引用;
3,将$a的值赋值为 2,值发生了该表,因为该zval 容器非地址引用,因此系统会从新建立一个 引用计数(指向数)为1,非地址引用而且值为int类型2 的新的zval 容器 指向$a ,因为 $a 再也不指向原zval容器,因此原容器的 引用计数(指向数) 减 1。spa
总结: 当经过值传递方式进行赋值时,因为两个变量保存的值彻底同样,为了 复用内存,PHP不会为新变量申请新的内存来存放值,而只是在原 zval 容器中将引用计数+1。只有当两个变量中的任何一个变量的值发生改变时,PHP才会从新为发生 值改变 的那个变量申请一个新内存,建立一个新的zval容器。debug
以上内容 就是php内核的一个重要的特性:引用计数 与 写时复制 原理。code