gpt4 book ai didi

php - 变量引用自身

转载 作者:IT王子 更新时间:2023-10-28 23:48:11 25 4
gpt4 key购买 nike

我阅读了很多关于如何在 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

事实证明我们正在创建链接本身?这怎么可能?

我所知道的清晰信息:

通常is_ref = 1只有当容器引用zval 两个或多个硬链接(hard link)变量时。

refcount - 是引用同一个 zval 容器的变量数,但不同之处在于 is_ref = 0is_ref 的不同 refcount = 1

如果在创建硬链接(hard link)时is_ref = 0,并且refcount > 1,我们会得到一个新的zval容器,如果我们通过值赋值——new zval container不会被创建。

如果 is_ref = 1,并且 refcount > 1 在创建硬链接(hard link)时不创建新的 zval,使用旧的。如果我们不创建硬链接(hard link),而是通过值进行分配 - 这意味着我们创建了新的 zval 容器。

P.S 我写这个是为了表明我理解我的要求并表明为什么我不理解我上面写的代码的行为

最佳答案

答案非常简单,如您问题的评论中所述。不过,我想我明白你的困惑从何而来,所以让我们来分解一下。 :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)}

仅使用一个变量将两个操作合并为一个,而不会破坏数据。因此:1 个变量 (refcount=1),它是对 数据 本身的引用 (is_ref=1)。

正如我们试图向您解释的那样,混淆源于原始问题背后的前提存在缺陷这一事实:您在这些示例中没有引用变量,您引用的是包含最初与所述变量关联的数据的内存区域。因此,您正在用另一个覆盖一个(原始的)“硬链接(hard link)”。唯一的区别是后者被标记为 PHP 内部原因。 (在引用计数 > 1 的情况下,引用不会在写入时被复制。)

关于php - 变量引用自身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40270343/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com