之前的文章中,我們說過變數賦值的問題,其中有一個問題是物件在進行變數賦值的時候,直接就是參考賦值,那么到底真實情況是怎樣呢?
之前變數賦值的文章
PHP的變數賦值
物件參考測驗
在繼續深入的學習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);
- $instance是實體化后的SimpleClass物件
- $assigned直接賦值
- $reference參考賦值
- 首先,我們給$instance物件定義了一個變數var
- 然后將$instance賦值為null
- 對于參考來說,$reference變數自然也為成了null
- 但是$assigned并沒有變成null,它依然是SimpleClass的實體物件,并且,劃重點哦:它有了var屬性
是不是很神奇,照理說,普通賦值是拷貝,兩個變數不會相互影響,而參考賦值是復制指標(相同的記憶體地址),修改任意一個變數其他的變數也會改變,但是物件的普通賦值貌似并不屬于它們中的任何一個,
$reference很好理解,本身使用&符號進行了賦值,表明了這個變數是一個參考賦值,它成為了$instance的快捷方式,$instance的一切變化它都都會跟著改變,這是變數層面的,
$assigned從代碼字面上看是一個普通賦值,不過物件是一種特殊的形態,它用普通賦值賦過來的值其實是物件的一個句柄,在PHP手冊中有一個Note是如此描述的:
首先,將PHP中的變數看成是一個一個的資料槽,這個資料槽可以保存一個基本型別(int、string、bool等),創建參考時,這個槽里保存的是記憶體地址,或者說是指向參考物件的一個指標,參考沒有拷貝操作,僅僅是將指標指向了原變數(參考資料結構),創建普通賦值時,則是拷貝的基本型別,
而物件則與基本型別不同,它不能直接保存在資料槽中,而是將物件的“句柄”保存在了資料槽,這個句柄是指向物件特定實體的識別符號,雖然句柄不是我們所能直觀操作的型別,但它也屬于基本型別,
當你獲取一個包含物件句柄的變數,并將其分配給另一個變數時,另一個變數獲取的是這個物件的句柄,(注意,不是參考!不是參考!不是參考!!),通過句柄,兩個變數都可以修改同一個物件,但是,這兩個變數并沒有直接關系,它們是兩個獨立的變數,其中一個變數修改為其他值時,并不會對另一個變數產生影響,只有該變數在修改物件內部的內容時,另一個變數因為持有相同的句柄,所以它的物件內容也會相應地發生改變,
Note原文:
https://www.php.net/manual/zh/language.oop5.basic.php#79856
總結
通過本文的分析,我們可以看出,變數賦值說白了就是變數層面的操作,它保存的永遠只是一個值而已,當普通賦值時,這個值就是一個基本型別,當參考賦值時,這個保存的基本型別就是一個指標,不管怎么樣,它也不會因為保存的是物件而將普通賦值直接轉變為參考賦值,真正的參考賦值是必須要加&符的,
這個內容有點繞,不過這樣的內容才能更體現自己的核心能力,讀書百遍其義自現,對于手冊中的很多知識本人也是來回不斷學習才能理解,上面的Note作者寫得非常好,英文好的朋友可以直接去看英文原版,
測驗代碼:
https://github.com/zhangyue0503/dev-blog/blob/master/php/201911/source/%E5%AF%B9%E8%B1%A1%E8%B5%8B%E5%80%BC%E5%9C%A8PHP%E4%B8%AD%E5%88%B0%E5%BA%95%E6%98%AF%E4%B8%8D%E6%98%AF%E5%BC%95%E7%94%A8%EF%BC%9F.php
參考檔案:
https://www.php.net/manual/zh/language.oop5.basic.php
關注公眾號:【硬核專案經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核專案經理】
B站ID:482780532
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/254316.html
標籤:PHP
上一篇:HashSet詳解
