unset傳遞的值是一個對象或者值的複製(比如傳遞數組,傳遞的是一個新的複製,而不是引用),結果原對象卻被銷毀了。好奇怪。
大神快來解答這個問題。以前一直用unset,今天突然想到了這個問題。
比如:
這時就會報出Undefined variable的錯誤。
正如舞林所說,這種銷毀變數的方式有可能是將引用計數減一。
但是這樣做:
這個時候,$a依然被銷毀。報出Undefined variable的錯誤的錯誤。
如果unset掉b,來看看結果:
只是銷毀了$b,$b雖然是$a的引用,但是$a沒有被銷毀。列印出hello
所以unset的機制並沒有那麼簡單。。
回複內容:
unset傳遞的值是一個對象或者值的複製(比如傳遞數組,傳遞的是一個新的複製,而不是引用),結果原對象卻被銷毀了。好奇怪。
大神快來解答這個問題。以前一直用unset,今天突然想到了這個問題。
比如:
這時就會報出Undefined variable的錯誤。
正如舞林所說,這種銷毀變數的方式有可能是將引用計數減一。
但是這樣做:
這個時候,$a依然被銷毀。報出Undefined variable的錯誤的錯誤。
如果unset掉b,來看看結果:
只是銷毀了$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