2016-10-26 28 views
23

我讀了很多關於如何構建變量在機器內部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的兩個或多個變量。

refcount - 是變量的數量指的是同一的zval容器,但不同的是,引用計數爲不同的作品與is_ref = 0is_ref = 1

如果is_ref = 0refcount > 1創建硬鏈接時,我們會得到一個新的zval容器,如果我們通過值進行賦值 - 不會創建新的zval容器。

如果is_ref = 1refcount > 1在創建硬鏈接時未創建新的zval,則使用舊的。如果我們不創建硬鏈接,但是通過值賦值 - 這意味着我們創建了新的zval容器。

PS我爲了表明明白,我只要求說明爲什麼我不明白,我在上面

+0

@RyanVincent這可能嗎?我怎樣才能使硬鏈接到相同的變量,即它本身 – MaximPro

+0

@RyanVincent我不瞭解你。我知道變量擁有一個Zval容器 – MaximPro

+0

也許有趣嗎? [PHP5參考可視化解釋](http://www.phpinsider.com/download/PHP5RefsExplained.pdf)。後來更容易理解。 –

回答

10

答案寫在代碼的行爲是非常簡單的,因爲在評論中解釋寫這你的問題。雖然,我想我明白你的困惑來自哪裏,所以我們來分解一下。 :D

首先給變量賦值,在內部PHP將它存儲在內存段中,並增加引用該地址的變量的計數器。 (Ref count = 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)到數據本身。

正如我們試圖向您解釋的那樣,混淆源自於原始問題背後的前提存在缺陷:在這些示例中,您沒有引用變量,您引用的是內存區域其中包含最初與所述變量相關聯的數據。所以你用另一個覆蓋了一個(原始的)「硬鏈接」。唯一的區別是後者標記爲這樣,因爲內部PHP原因。 (在refcounts> 1的情況下,參考文獻不會被複制。)

+0

如果我正確理解你的話:在php中沒有引用這種類型的數據的概念,只有變量存儲指向zval容器的指針。但是,如果是這樣的話,那麼在php中沒有特殊的變量,並且將你的概念打破成碎片 – MaximPro

+0

你在想什麼樣的特殊變量? – ChristianF

+0

@MaximPro我已經更新了我的答案,以稍微不同的方式解釋它,並希望更清晰地爲您解答。 – ChristianF