我读了很多关于如何在机器Zend中构造变量的文章,发现了一件我无法解释的有趣的事情:
$int = 100;
xdebug_debug_zval('int'); /// int:(refcount=1,is_ref=0),int 100
$int = &$int;
xdebug_debug_zval('int'); /// int:(refcount=1,is_ref=1),int 100
Run Code Online (Sandbox Code Playgroud)
事实证明我们正在创建自己的链接?这怎么可能?
清楚我所知道的信息:
通常is_ref = 1只有当容器引用zval两个或多个硬链接变量时.
refcount- 变量的数量是指同一个zval容器,但区别在于不同的refcount用is_ref = 0和is_ref = 1.
如果is_ref = 0和refcount > 1创建硬链接时,我们得到一个新的zval容器,如果我们按值进行赋值 - 将不会创建新的zval容器.
如果is_ref = 1,并且refcount > 1在创建硬链接时未创建新的zval,则使用旧的.如果我们不创建硬链接,但是通过值进行分配 - 这意味着我们创建了新的zval容器.
PS我写这篇文章是为了表明理解我问并说明为什么我不理解我上面写的代码的行为
Chr*_*anF 10
答案非常简单,正如您对问题的评论中所解释的那样.虽然,我想我明白你的困惑来自哪里,所以让我们打破这个.:d
首先为变量赋值,内部PHP将其存储在内存段中,并增加引用该地址的变量的计数器.(参考计数= 1).所有直截了当,直到这一点.
然后,重新使用该变量将引用(C语言中的指针)存储到此内存地址.PHP手册将此解释为存储对变量的引用,以使非C程序员更容易,这就是(我认为)您的困惑来自哪里.没有引用内部变量的引用,只有变量链接的数据.由于您重新使用该变量来存储此引用,因此引用计数不会增加:仍然只有一个变量指向此内存段.但是,它不再是普通的PHP变量,而是数据的引用(指针).
编辑,添加:
实现相同结果的另一种方法是使用两个变量然后unset使用第一个变量.代码示例:
$a = 100; // refcount += 1
xdebug_debug_zval ('a'); // refcount=1,is_ref=0 -> zval {value=100,type=int (addr=0x78765asd)}
$b =& $a; // refcount += 1
xdebug_debug_zval ('a') // refcount=2,is_ref=0 -> zval {value=100,type=int (addr=0x78765asd)}
xdebug_debug_zval ('b') // refcount=2,is_ref=1 -> zval {value=100,type=int (addr=0x78765asd)}
unset ($a); // refcount -= 1
xdebug_debug_zval ('b') // refcount=1,is_ref=1 -> zval {value=100,type=int (addr=0x78765asd)}
Run Code Online (Sandbox Code Playgroud)
仅使用一个变量将两个操作合并为一个,而不会破坏数据.因此:1个变量(refcount = 1),它是数据本身的引用(is_ref = 1).
正如我们试图向您解释的那样,混淆源于这样一个事实,即原始问题背后的前提是有缺陷的:您没有在这些示例中引用变量,而是引用包含最初关联数据的内存区域用所述变量.所以你用另一个覆盖了一个(原始的)"硬链接".由于内部PHP的原因,唯一的区别是后者被标记为这样.(在refcounts> 1的情况下,引用不会在写入时被复制)
| 归档时间: |
|
| 查看次数: |
605 次 |
| 最近记录: |