PHP unset函數好奇怪

來源:互聯網
上載者:User
unset傳遞的值是一個對象或者值的複製(比如傳遞數組,傳遞的是一個新的複製,而不是引用),結果原對象卻被銷毀了。好奇怪。
大神快來解答這個問題。以前一直用unset,今天突然想到了這個問題。
比如:


這時就會報出Undefined variable的錯誤
正如舞林所說,這種銷毀變數的方式有可能是將引用計數減一。
但是這樣做:

這個時候,$a依然被銷毀。報出Undefined variable的錯誤的錯誤。
如果unsetb,來看看結果:

只是銷毀了$b,$b雖然是$a的引用,但是$a沒有被銷毀。列印出hello
所以unset的機制並沒有那麼簡單。。

回複內容:

unset傳遞的值是一個對象或者值的複製(比如傳遞數組,傳遞的是一個新的複製,而不是引用),結果原對象卻被銷毀了。好奇怪。
大神快來解答這個問題。以前一直用unset,今天突然想到了這個問題。
比如:


這時就會報出Undefined variable的錯誤
正如舞林所說,這種銷毀變數的方式有可能是將引用計數減一。
但是這樣做:

這個時候,$a依然被銷毀。報出Undefined variable的錯誤的錯誤。
如果unsetb,來看看結果:

只是銷毀了$b,$b雖然是$a的引用,但是$a沒有被銷毀。列印出hello
所以unset的機制並沒有那麼簡單。。

第一段代碼 a和b是兩塊不同的記憶體 所以unset掉兩者 根本沒影響
第二段代碼 b引用a 使得對應的zval ref_count+1 is_ref +1 此時不管unset掉a或者b 只是斷了一根引用對另外的那個值沒影響 還是指向的那塊地區

變數引用次數-1,只要有對該記憶體塊的引用,該記憶體塊就不會被銷毀

update:
昨天寫答案提交探索服務器在調皮的維護,以為沒發出去呢...
TIPI有寫具體的內容:
http://www.php-internals.com/book/?p=chapt03/03-01-00-variables-structure
//變數結構體

http://www.php-internals.com/book/?p=chapt03/03-06-01-var-define-and-init
//變數的賦值和銷毀,這裡詳細講解了引用計數

我覺得你說得好像不成立。。

$o = new stdClass();$o->var = 123;$new_o = $o; //等於$new_o = & $o;unset($new_o);var_dump($o);

對象賦值本身就是引用賦值,但是unset 引用的變數 只是把引用給銷毀了,並不會銷毀原變數

我的理解是這個樣子

...你 確定?

------------update-------------
把評論裡的拿上來
unset只是斷開了變數 名和值 之間的綁定

引用:
"該函數只有在變數值所佔空間超過256位元組長的時候才會釋放記憶體"
&&
"有當指向該值的所有變數(比如有引用變數指向該值)都被銷毀後,地址才會被釋放"

unset($a)無論你$a是怎麼得到的(直接賦值$a=true、傳值$a=$b、傳址$a=&$b),以及對$a進行過什麼操作(傳值給別的變數$b=$a或傳址$b=&$a),它都會斷掉$a的引用,並把$a抹成null。
至於被賦值的那個對象是不受影響的,引用計數自己會處理好。

同意樓上幾位的回答,如果LZ的問題依然存在,不妨貼出你的代碼可以更好的說明情況。

不過我想通過以下代碼給LZ提個醒:

$foo = true;$bar = &$foo;unset($foo);var_dump($bar);  // 結果是true,而不是null

另外反過來一樣

$foo = true;$bar = &$foo;unset($bar);var_dump($foo);  // 結果依然是true,而不是null

可以看出:即時向unset傳遞一個變數的引用,也不會把該變數銷毀
所以我不太能理解LZ的問題是怎麼一回事……

這段代碼是我從別處搜尋來的,我認為應該能夠解決你的疑問!
如果在函數中 unset() 一個通過引用傳遞的變數,則只是局部變數被銷毀,而在調用環境中的變數將保持調用 unset() 之前一樣的值。

   

上邊的例子將輸出:

something
something

樓主第二個測試,可以輸出$b 試試,一樣沒有被銷毀

參考這個
http://php.net/manual/zh/features.gc.refcounting-basics.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.