的基礎
要了解發生了什麼,你需要挖掘到PHP的內部,看看內存管理。
引擎蓋下,一個值表示這樣的:的指向此值的變量
+--------------------+
| (type) {{ VALUE }} |
| refcount = a |
| isref = b |
+--------------------+
基準計數器a
計數的數目。 isref
標誌顯示該值是按值(即$a = VALUE
)還是通過引用(即$a =& VALUE
)分配的。
假設下面的情況:
+--------------------------+
$a ------------->| (int) 58 | $a = 58
| refcount = 1 ; isref = 0 |
+--------------------------+
如果複製的$a
價值爲$b
,PHP只是遞增refcount
中爲了節省內存(即不存儲兩次相同的值):
+--------------------------+
$a -------+----->| (int) 58 | $b = $a
| | refcount = 2 ; isref = 0 |
| +--------------------------+
|
|
$b -------+
如果你改變$ b的值到別的東西,將創建一個新的價值,並引用計數到58
遞減:
+--------------------------+
$a ------------->| (int) 58 | $b = 'hello'
| refcount = 1 ; isref = 0 |
+--------------------------+
+--------------------------+
$a ------------->| (string) 'hello' |
| refcount = 1 ; isref = 0 |
+--------------------------+
在參考的情況下,isref
標誌被設置爲true
,和一個變化的影響都標識符:
+--------------------------+
$a -------+----->| (int) 58 | $b =& $a
| | refcount = 2 ; isref = 1 |
| +--------------------------+
|
|
$b -------+
。
+--------------------------+
$a -------+----->| (int) 21 | $b = 21
| | refcount = 2 ; isref = 1 |
| +--------------------------+
|
|
$b -------+
關於對象引用
你經常能聽到,在PHP中,對象是通過引用透明地傳遞。 According to the doc,這不完全正確。名稱標識符$a
包含一個對象標識符,這就是函數之間傳遞的內容。我會說明這個標識符與下面object
類型的整數,我不知道該怎樣它的真正的引擎蓋下完成的想法,但解釋持有;-)
不要混淆標識,即變量名與對象標識符,即對象在內存中的編號。
+--------------------------+
$a ------------->| (object) 547654764237685 | $a = new FooBar();
| refcount = 1 ; isref = 0 |
+--------------------------+
別的地方在內存中,PHP店我們只是標識547654764237685
創建的FooBar
實例。當您使用值(object) 547654764237685
時,PHP會自動檢索所述對象並允許您透明地使用它。
那麼發生了什麼?
讓我們一行一行地檢查你的代碼。
您首先創建一個新的SimpleClass
實例。
+--------------------------+
$instance ------>| (object) 547654764237685 | $instance = new SimpleClass();
| refcount = 1 ; isref = 0 |
+--------------------------+
然後你做一個值分配給$assigned
,即遞增refcount
:
+--------------------------+
$instance ---+-->| (object) 547654764237685 | $assigned = $instance;
| | refcount = 2 ; isref = 0 |
| +--------------------------+
|
|
$assigned ---+
第三行引用$reference
到$instance
。因爲價值的refcount
大於一和,因爲它不是已經是一個參考(isref = 0
),PHP在內存中創建一個新的類似的價值:
+--------------------------+
$instance ---+-->| (object) 547654764237685 | $reference =& $instance;
| | refcount = 2 ; isref = 1 |
| +--------------------------+
|
|
$reference --+
+--------------------------+
$assigned ------>| (object) 547654764237685 |
| refcount = 1 ; isref = 0 |
+--------------------------+
的三個標識符$instance
,$assigned
和$reference
評估,以非常相同對象,因爲對象標識符保持不變。儘管如此,我們現在在內存中有兩個不同的值。
這就是爲什麼電話$instance->var = '$assigned will have this value';
影響$instance->var
,$assigned->var
和$reference->var
。
現在,當您設置$instance
到null
,因爲$reference
引用相同的值,都受到影響:
+--------------------------+
$instance ---+-->| (NULL) | $instance = null;
| | refcount = 2 ; isref = 1 |
| +--------------------------+
|
|
$reference --+
+--------------------------+
$assigned ------>| (object) 547654764237685 |
| refcount = 1 ; isref = 0 |
+--------------------------+
的$assigned
的對象引用不會受到影響,因爲它是一個單獨的值,從而$assigned
仍會調用目的。
「爲什麼$分配NULL不會成爲NULL,當我們將NULL分配給$ instance?」因爲它們是兩個完全不同的變量,並且$分配既不知道也不關心你對$ instance做什麼。 – Boann
很長一段時間以來,您已獲得本網站最好的答案之一 - 謹慎回覆作者,或者至少接受它? – halfer
繼續從你不回覆我,或下面的優秀答案,我已經downvoted。 – halfer