<?php
// 什么是引用变量?在PHP当中,用什么符号定义引用变量?
// PHP的引用变量的概念
// :在PHP中引用意味着用不同的名字访问同一个变量内容。
// 定义方式
// :使用&符号
#例1:不适用引用变量
$a = range(0, 1000);
var_dump(memory_get_usage()); //int(401536)
//此时$b的赋值不会从开辟一块新的空间,$a和$b指向同一块空间
$b = $a;
var_dump(memory_get_usage()); //int(401536)
//当给$a从新赋值时,会给$a 从新开辟一块空间
$a = range(0,1000);
var_dump(memory_get_usage()); //int(430256)
#例2:使用引用变量
$a = range(0, 1000);
var_dump(memory_get_usage()); //int(401536)
//此时$b的赋值不会从开辟一块新的空间,$a和$b指向同一块空间
$b = &$a; //代表$a和$b永远指向同一块空间
var_dump(memory_get_usage()); //int(401536)
//当给$a从新赋值时,会给$a 从新开辟一块空间
$a = range(0,1000);
var_dump(memory_get_usage()); //int(401536)
// 通过zval可以看到引用变量的工作原理
// 在kv当中,我们有一个zval结构体,在PHP当中我们都是通过zval引擎来管理变量,zval结构体就是我们的变量容器。
// 使用xdebug_debug_zval查看变量结构
// php调试函数xdebug_debug_zval和debug_backtrace(需要安装xdebug 参考:https://blog.csdn.net/qq_35770969/article/details/80757959 )
$c = range(0, 9);
xdebug_debug_zval('c');
// 结果:
// c:
// (refcount=1, is_ref=0)
// array (size=10)
// 0 => (refcount=0, is_ref=0)int 0
// 1 => (refcount=0, is_ref=0)int 1
// 2 => (refcount=0, is_ref=0)int 2
// 3 => (refcount=0, is_ref=0)int 3
// 4 => (refcount=0, is_ref=0)int 4
// 5 => (refcount=0, is_ref=0)int 5
// 6 => (refcount=0, is_ref=0)int 6
// 7 => (refcount=0, is_ref=0)int 7
// 8 => (refcount=0, is_ref=0)int 8
// 9 => (refcount=0, is_ref=0)int 9
//refcount=1 内存空间中有一个变量指向这个空间
//is_ref=0 是不是引用
//size=10 长度
//
//定义一个变量d,把变量c的之给d
$d = $c ;
xdebug_debug_zval('c');
// 结果:
// c:
// (refcount=2, is_ref=0)
// array (size=10)
// 0 => (refcount=0, is_ref=0)int 0
// 1 => (refcount=0, is_ref=0)int 1
// 2 => (refcount=0, is_ref=0)int 2
// 3 => (refcount=0, is_ref=0)int 3
// 4 => (refcount=0, is_ref=0)int 4
// 5 => (refcount=0, is_ref=0)int 5
// 6 => (refcount=0, is_ref=0)int 6
// 7 => (refcount=0, is_ref=0)int 7
// 8 => (refcount=0, is_ref=0)int 8
// 9 => (refcount=0, is_ref=0)int 9
// refcount=2 把变量c的之给d后,refcount的值变为2 ,证明目前有两个变量b和c指向这块空间
// is_ref=0 不变
//
$c = range(0, 9) ;
xdebug_debug_zval('c');
// 结果:
// c:
// (refcount=1, is_ref=0)
// array (size=10)
// 0 => (refcount=0, is_ref=0)int 0
// 1 => (refcount=0, is_ref=0)int 1
// 2 => (refcount=0, is_ref=0)int 2
// 3 => (refcount=0, is_ref=0)int 3
// 4 => (refcount=0, is_ref=0)int 4
// 5 => (refcount=0, is_ref=0)int 5
// 6 => (refcount=0, is_ref=0)int 6
// 7 => (refcount=0, is_ref=0)int 7
// 8 => (refcount=0, is_ref=0)int 8
// 9 => (refcount=0, is_ref=0)int 9
//
// refcount=1 因为$c进行了写操作,d和c不再指向同一块空间
//
//
$q = range(0, 9);
xdebug_debug_zval('q');
$w = &$q ;
xdebug_debug_zval('q');
$q = range(0, 9) ;
xdebug_debug_zval('q');
// 结果:
// q:
// (refcount=1, is_ref=0)
// array (size=10)
// 0 => (refcount=0, is_ref=0)int 0
// 1 => (refcount=0, is_ref=0)int 1
// 2 => (refcount=0, is_ref=0)int 2
// 3 => (refcount=0, is_ref=0)int 3
// 4 => (refcount=0, is_ref=0)int 4
// 5 => (refcount=0, is_ref=0)int 5
// 6 => (refcount=0, is_ref=0)int 6
// 7 => (refcount=0, is_ref=0)int 7
// 8 => (refcount=0, is_ref=0)int 8
// 9 => (refcount=0, is_ref=0)int 9
// q:
// (refcount=2, is_ref=1)
// array (size=10)
// 0 => (refcount=0, is_ref=0)int 0
// 1 => (refcount=0, is_ref=0)int 1
// 2 => (refcount=0, is_ref=0)int 2
// 3 => (refcount=0, is_ref=0)int 3
// 4 => (refcount=0, is_ref=0)int 4
// 5 => (refcount=0, is_ref=0)int 5
// 6 => (refcount=0, is_ref=0)int 6
// 7 => (refcount=0, is_ref=0)int 7
// 8 => (refcount=0, is_ref=0)int 8
// 9 => (refcount=0, is_ref=0)int 9
// q:
// (refcount=2, is_ref=1)
// array (size=10)
// 0 => (refcount=0, is_ref=0)int 0
// 1 => (refcount=0, is_ref=0)int 1
// 2 => (refcount=0, is_ref=0)int 2
// 3 => (refcount=0, is_ref=0)int 3
// 4 => (refcount=0, is_ref=0)int 4
// 5 => (refcount=0, is_ref=0)int 5
// 6 => (refcount=0, is_ref=0)int 6
// 7 => (refcount=0, is_ref=0)int 7
// 8 => (refcount=0, is_ref=0)int 8
// 9 => (refcount=0, is_ref=0)int 9
//
//
// 从三次打印的值中, q 在第一次range 入职后 refcount 的值是1,代表有一个变量指向这个空间,当 $w = &$q ;后,有两个变量指向这块空间,当q从新赋值后,依然有两个变量指向这块空间;并且当引用后 is_ref=1 的值变成了1
// 我们