關於PHP5後“預設情況下物件是通過引用傳遞的”思考

kumfo發表於2019-02-16

首先引發這篇博文的是來源於這篇帖子:https://segmentfault.com/q/10…

經過了思考之後,我決定把回答思考變成部落格做一下記錄,如有不對之處,歡迎指正。

指標與引用

  1. 首先,引用和指標是不一樣的,指標在C語言裡的概念是表示變數的地址;
  2. 引用在PHP裡是表示變數2是變數1的別名,如:
$a = `hello`;
$b = &$a;

此時可以說$b就是$a,$a就是$b;是同一個東西,比如你英文名叫 Steven,中文名叫 二狗子,不管叫啥,都是你。

PHP中的物件傳遞

然後說一下PHP5之後的“預設情況下PHP的物件是通過引用傳遞的這件事情。
如:

class Obj() {
    public $o = `hello`;
}
$a = new Obj();
$b = $a;
$c = &$a;

此時,$b=$a其實表示的並不是$b$a的引用,$a$b可以說是沒什麼關係的,有關係的是例項化Obj類得到的物件。
也就是說,此時$a和$b都是例項化Obj後得到的物件,而$b=$a唯一產生的是$b$a這裡得到了例項化Obj後的引用;
然後看$c = &$a
此時是$c$a的引用,也就是說$c就是$a
假設:

unset($b);
unset($c);

那麼unset($b)只是刪除了例項化Obj後得到的物件的一次引用計數,
unset($c)則刪除了$a$b(因為兩個表示同一個東西);

同樣的,假設:

$a->o = `test`;
echo $b->o; // string `test`

雖然說$a和$b`沒什麼關係`,但是與例項化後的物件有關係,也就是$a改變的是例項化後的物件的資料,而$b的呼叫也是呼叫了這個物件的資料,所以從一定層面上看起來其實是有關係的。

再一個假設這樣說還不明白的話,從我們web的業務邏輯來看。

使用者A和使用者B都登陸了網站,使用者A改變了儲存評論的資料表的資料,使用者B假設去取這條資料,則使用者B獲取到就是修改後的資料,而其實使用者A和使用者B是沒什麼關係的。

而引用其實類似於使用者A同時在手機端和電腦端登陸,然後改變了評論資料表的資料,不管是在手機端還是在電腦端重新獲取資料都是修改過的,但是實際上就是一個人。

引用計數

我文中提到了一個引用計數的名詞,這裡又涉及到PHP中的另外一個問題,就是PHP的引用計數,這個可以參考PHP官方的文件,我覺得已經很詳細了:
http://php.net/manual/zh/feat…

相關文章