PHP 引用計數器 通俗版解釋_PHP教程

來源:互聯網
上載者:User

PHP 引用計數器 通俗版解釋


概述

最近看PHP中的引用計數器部分,首先被各種繞暈,然後通過看部落格和分析後,總結了一個比較通俗的解釋,能協助自己很好地記憶,也希望能協助到各位讀者。這裡分享一遍博文,是比較正統的解釋:PHP變數之引用(http://hilojack.sinaapp.com/?p=1392)。

建議

研究PHP引用計數器的變化可以通過安裝Xdebug擴充來學習,安裝後直接調用 xdebug_debug_zval('var') 來看變數 $var的引用計數器情況。

基礎知識

談引用計數器需要對PHP中變數的儲存、引用計數的機制有所瞭解,引用計數當然是節約記憶體,在不影響語義正確性的前提下,讓多個變數符號共用一個記憶體值空間(又稱為變數容器)。引用計數什麼時候發生變化:賦值。 賦值又有兩種: 值傳遞賦值和引用賦值。比較難以理解的是引用賦值。引用計數的另一個作用就是指示什麼時候可以共用同一空間,什麼時候必須進行變數分離(另開闢空間)。

通俗解釋

為了便於理解和記憶,本人對賦值中的各種情景給以通俗的解釋,不要與現實情況對號入座,。

& 號是結合,可以相當於結婚,但是PHP中允許多個人一起結婚(即一夫多妻制或一妻多夫制),這個比較變態。 注意結婚必須同居,分居是不行的。除了結婚外還有一種形態叫 合租。合租也是同居,但是沒有任何關係,允許多人合租,這個是合情合理的。當然還有一種情況是獨居,這個比較容易理解。以下面的例子說明賦值語句與這三種狀態對應關係:

情景一:

$a = "a";  // $a 獨居, is_ref = 0, refcount = 1;$b = $a;   // $a 與 $b 合租, is_ref = 0, refcount = 2;
情景二:

$a = "a"; // $a 獨居, is_ref = 0, refcount = 1;$b = &$a; // $a 與 $b 結婚, is_ref = 1, refcount = 2;
上面可以看出, is_ref可以理解為結婚證,=1 表示兩個和多個變數是結婚關係, =0沒有結婚(可以合租或同居),refcount表示了多少個變數住在一起了,=1表示獨居,>1表示多人同居(記住,結婚必須同居,但同居未必是結婚關係)。

下面開始分析賦值時的變數變化關係:

情景一:

$a = "a";  // $a 獨居, is_ref = 0, refcount = 1;$b = $a;   // $a 與 $b 合租, is_ref = 0, refcount = 2;$va = "b"; // $va 獨居, is_ref = 0, refcount = 1;$vb = $va; // $va 和 $vb 合租, is_ref = 0, refcount = 2;$a = $va;  // $a是單身,$va也是單身,因此 $a 搬去與 $va 同居,現在$a,$va,$vb三人同居賦值後: $a: is_ref = 0, refcount = 3, string = "xyz"$b: is_ref = 0, refcount = 1, string = "qwe"$va: is_ref = 0, refcount = 3, string "xyz"$vb: is_ref = 0, refcount = 3, string "xyz"

情景二:

$a = "a";  // $a 獨居, is_ref = 0, refcount = 1;$b = &$a;   // $a 與 $b 結婚, is_ref = 1, refcount = 2;$va = "b"; // $va 獨居, is_ref = 0, refcount = 1;$vb = $va; // $va 和 $vb 合租, is_ref = 0, refcount = 2;$a = $va;  // $a是已婚, $a 不能隨便單獨搬出去,賦值會使$va的值拷貝給$a,其他關係不變$a: is_ref = 1, refcount = 2, string = "xyz"$b: is_ref = 1, refcount = 2, string = "xyz"$va: is_ref = 0, refcount = 2, string "xyz"$vb: is_ref = 0, refcount = 2, string "xyz"

情景三:

$a = "a";  // $a 獨居, is_ref = 0, refcount = 1;$b = &$a;   // $a 與 $b 結婚, is_ref = 1, refcount = 2;$va = "b"; // $va 獨居, is_ref = 0, refcount = 1;$vb = &$va; // $va 和 $vb 結婚, is_ref = 1, refcount = 2;$a = $va;  // $a是已婚, 與情景二相同,值拷貝,關係不變賦值後:$a: is_ref = 1, refcount = 2, string = "xyz"$b: is_ref = 1, refcount = 2, string = "xyz"$va: is_ref = 1, refcount = 2, string "xyz"$vb: is_ref = 1, refcount = 2, string "xyz"

情景四:

$a = "qwe";  // $a 獨居, is_ref = 0, refcount = 1;$b = $a;   // $a 與 $b 同居, is_ref = 0, refcount = 2;$va = "xyz"; // $va 獨居, is_ref = 0, refcount = 1;$vb = &$va; // $va 和 $vb 結婚, is_ref = 1, refcount = 2;$a = $va;  // $a 想與 $va同居(而非結婚),但是$va已婚的,因此 $a只能從$b那裡搬出來,重新分配個房子,值與$va一樣(術語叫:變數分離);$va和$vb關係不變賦值後: $a: is_ref = 0, refcount = 1, string = "xyz"$b: is_ref = 0, refcount = 1, string = "qwe"$va: is_ref = 1, refcount = 2, string "xyz"$vb: is_ref = 1, refcount = 2, string "xyz"

情景五:

$a = "qwe";  // $a 獨居, is_ref = 0, refcount = 1;$b = $a;   // $a 與 $b 同居, is_ref = 0, refcount = 2;$va = "xyz"; // $va 獨居, is_ref = 0, refcount = 1;$vb = $va; // $va 和 $vb 同居, is_ref = 0, refcount = 2;$a = &$va;  // $a 想與 $va結婚,現在$a 和 $va 都是單身但是都有室友了,因此他們各自從原來的地方搬出來,然後分個新房子,值與$va原來的一樣賦值後: $a: is_ref = 1, refcount = 2, string = "xyz"$b: is_ref = 0, refcount = 1, string = "qwe"$va: is_ref = 1, refcount = 2, string "xyz"$vb: is_ref = 0, refcount = 1, string "xyz"

情景六:

$a = "qwe";  // $a 獨居, is_ref = 0, refcount = 1;$b = $a;   // $a 與 $b 同居, is_ref = 0, refcount = 2;$va = "xyz"; // $va 獨居, is_ref = 0, refcount = 1;$vb = &$va; // $va 和 $vb 結婚, is_ref = 1, refcount = 2;$a = &$va;  // $a 想與 $va 結婚,但是 $va 是已婚的,而 $a 是單身,因此 $a 搬過去和 $va 住,$va 現在有兩個配偶:$vb 和 $a賦值後: $a: is_ref = 1, refcount = 3, string = "xyz"$b: is_ref = 0, refcount = 1, string = "qwe"$va: is_ref = 1, refcount = 3, string "xyz"$vb: is_ref = 1, refcount = 3, string "xyz"

情景七:

$a = "qwe";  // $a 獨居, is_ref = 0, refcount = 1;$b = &$a;   // $a 與 $b 結婚, is_ref = 1, refcount = 2;$va = "xyz"; // $va 獨居, is_ref = 0, refcount = 1;$vb = $va; // $va 和 $vb 同居, is_ref = 0, refcount = 2;$a = &$va;  // $a 想與 $va 結婚,但是 $a 是已婚的,$va 是單身, 解決辦法是 $a 離婚後和 $va 結婚,同時 $va 從與 $vb合租的地方搬出來賦值後: $a: is_ref = 1, refcount = 2, string = "xyz"$b: is_ref = 0, refcount = 1, string = "qwe"$va: is_ref = 1, refcount = 2, string "xyz"$vb: is_ref = 0, refcount = 1, string "xyz"


情景八:

$a = "qwe";  // $a 獨居, is_ref = 0, refcount = 1;$b = &$a;   // $a 與 $b 結婚, is_ref = 1, refcount = 2;$va = "xyz"; // $va 獨居, is_ref = 0, refcount = 1;$vb = &$va; // $va 和 $vb 結婚, is_ref = 1, refcount = 2;$a = &$va;  // $a 想與 $va 結婚,但是 $a和$va都是已婚的,誰離婚?$a!,因為是$a主動想和$va結婚,// $a 離婚後$va住一起,$va 現在有兩個配偶:$vb 和 $a賦值後: $a: is_ref = 1, refcount = 3, string = "xyz"$b: is_ref = 0, refcount = 1, string = "qwe"$va: is_ref = 1, refcount = 3, string "xyz"$vb: is_ref = 1, refcount = 3, string "xyz"

以上分析了簡單變數賦值的各種情形,不包括自引用的情況。概況來講:

簡單賦值 就是同居,需考察等號左側變數的is_ref(即是否已婚),若 is_ref = 1,則值拷貝,否則考慮左側便令,能否在不另外分配記憶體的情形下,與右側變數共用同一儲存空間(同居),此時要考察右側是否是已婚,若是,則不能同居,變數分離,若右側變數也是單身,則直接共用同一記憶體,所有同居者都遵循 COW(寫時拷貝)的原則。

引用賦值 就是結合, 需先考察右側變數的引用情況, 若 is_ref = 1,則直接 refcount ++, 出現多人結合的情況, 若右側是非引用的(is_ref = 0),那還需考察右側是否是獨居,若是獨居,則 左右兩個變數共用右側變數空間,否則右側變數從原來的地方分離出來和左側開闢新空間。 只要是引用賦值,那麼左側變數總是要與之前結合的或共用的變數進行分離。







http://www.bkjia.com/PHPjc/875473.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/875473.htmlTechArticlePHP 引用計數器 通俗版解釋 概述 最近看PHP中的引用計數器部分,首先被各種繞暈,然後通過看部落格和分析後,總結了一個比較通俗的解釋,...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.