以前的文章中,咱們說過變量賦值的問題,其中有一個問題是對象在進行變量賦值的時候,直接就是引用賦值。那麼到底真實狀況是怎樣呢?php
以前變量賦值的文章git
PHP的變量賦值github
對象引用測試微信
在繼續深刻的學習PHP手冊後,發現原來對象還真不是直接的引用複製。經過下面手冊中的例子來進行分析:數據結構
class SimpleClass {} $instance = new SimpleClass(); $assigned = $instance; $reference = &$instance; $instance->var = '$assigned will have this value'; $instance = null; // $instance and $reference become null var_dump($instance); var_dump($reference); var_dump($assigned);
是否是很神奇,照理說,普通賦值是拷貝,兩個變量不會相互影響。而引用賦值是複製指針(相同的內存地址),修改任意一個變量其餘的變量也會改變。可是對象的普通賦值貌似並不屬於它們中的任何一個。oop
$reference很好理解,自己使用&符號進行了賦值,代表了這個變量是一個引用賦值。它成爲了$instance的快捷方式,$instance的一切變化它都都會跟着改變。這是變量層面的。學習
$assigned從代碼字面上看是一個普通賦值。不過對象是一種特殊的形態,它用普通賦值賦過來的值實際上是對象的一個句柄。在PHP手冊中有一個Note是如此描述的:測試
首先,將PHP中的變量當作是一個一個的數據槽。這個數據槽能夠保存一個基本類型(int、string、bool等)。建立引用時,這個槽裏保存的是內存地址,或者說是指向引用對象的一個指針,引用沒有拷貝操做,僅僅是將指針指向了原變量(參考數據結構)。建立普通賦值時,則是拷貝的基本類型。this
而對象則與基本類型不一樣,它不能直接保存在數據槽中,而是將對象的「句柄」保存在了數據槽。這個句柄是指向對象特定實例的標識符。雖然句柄不是咱們所能直觀操做的類型,但它也屬於基本類型。.net
當你獲取一個包含對象句柄的變量,並將其分配給另外一個變量時,另外一個變量獲取的是這個對象的句柄。(注意,不是引用!不是引用!不是引用!!)。經過句柄,兩個變量均可以修改同一個對象。可是,這兩個變量並無直接關係,它們是兩個獨立的變量,其中一個變量修改成其餘值時,並不會對另外一個變量產生影響。只有該變量在修改對象內部的內容時,另外一個變量由於持有相同的句柄,因此它的對象內容也會相應地發生改變。
Note原文:
https://www.php.net/manual/zh/language.oop5.basic.php#79856
總結
經過本文的分析,咱們能夠看出,變量賦值說白了就是變量層面的操做。它保存的永遠只是一個值而已。當普通賦值時,這個值就是一個基本類型。當引用賦值時,這個保存的基本類型就是一個指針。無論怎麼樣,它也不會由於保存的是對象而將普通賦值直接轉變爲引用賦值,真正的引用賦值是必需要加&符的。
這個內容有點繞,不過這樣的內容才能更體現本身的核心能力。讀書百遍其義自現,對於手冊中的不少知識本人也是來回不斷學習才能理解。上面的Note做者寫得很是好,英文好的朋友能夠直接去看英文原版。
關注公衆號:【硬核項目經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、項目管理學習資料
知乎、公衆號、抖音、頭條搜索【硬核項目經理】
B站ID:482780532