define('NL', "\r\n");
$v1 = 'shared'; //原始变量 //生成一个变量容器
xdebug_debug_zval('v1'); //(refcount=0, is_ref=0)string 'shared' (length=6)
$v2 = &$v1; //引用计数加1
xdebug_debug_zval('v1'); //(refcount=2, is_ref=1)string 'shared' (length=6)
$v3 = &$v2; //引用计数加1
xdebug_debug_zval('v1'); //(refcount=3, is_ref=1)string 'shared' (length=6)
$v4 = &$v3; //引用计数加1
xdebug_debug_zval('v4'); //(refcount=4, is_ref=1)string 'shared' (length=6)
echo 'before:'.NL;
echo 'v1=' . $v1 . NL;
echo 'v2=' . $v2 . NL;
echo 'v3=' . $v3 . NL;
echo 'v4=' . $v4 . NL.'<br>';
//xdebug_debug_zval('v1');
//xdebug_debug_zval('v2');
// detach messy
$detach = $v1; //用$detach保存$v1 不同内存地址
xdebug_debug_zval('v1'); //(refcount=4, is_ref=1)string 'shared' (length=6) //1234共享一个内存地址
xdebug_debug_zval('detach'); //(refcount=0, is_ref=0)string 'shared' (length=6) //独立一个内存地址
unset($v1); //unset掉$v1 所以与 $v1关联得变量容器减1
xdebug_debug_zval('v1'); //(refcount=0, is_ref=0)*uninitialized* 未初始化
xdebug_debug_zval('v2'); //(refcount=3, is_ref=1)string 'shared' (length=6) //234共享一个内存地址
$v1 = $detach;
xdebug_debug_zval('v1'); //(refcount=0, is_ref=0)string 'shared' (length=6) //独立一个内存地址
// detach pretty, but slower
eval(detach('$v2')); // 覆盖变量容器$detach unset $v2
xdebug_debug_zval('v2'); //(refcount=0, is_ref=0)string 'shared' (length=6) //此时v2为独立一个内存地址
xdebug_debug_zval('v3'); //(refcount=2, is_ref=1)string 'shared' (length=6) //v3跟v4是同一内存地址
xdebug_debug_zval('v3'); //(refcount=2, is_ref=1)string 'shared' (length=6) //v3跟v4是同一内存地址
$v1 .= '?';
$v2 .= ' no more';
$v3 .= ' stiooo';
$v4 .= 'll';
echo NL.'after:'.NL;
echo 'v1=' . $v1 . NL;
echo 'v2=' . $v2 . NL;
echo 'v3=' . $v3 . NL;
echo 'v4=' . $v4 . NL;
function detach($v) {
$e = '$detach = ' . $v . ';';
$e .= 'unset('.$v.');';
$e .= $v . ' = $detach;';
return $e;
}