PHP中的foreach
如果數組的is_ref為1,則直接迴圈原數組
如果foreach($arr as &$v){}最終會把$arr的is_ref設為1,直接迴圈原數組
如果數組is_ref為0,但引用計數大於1,會拷貝數組,並開闢新的記憶體空間,迴圈被拷貝的數組
以上說的有沒有問題呢?
還有比較糾結的一個問題
在foreach之初,就把數組的引用計數+1呢,然後數組改變的時候,$arr[$k]=111或者運行current等函數,copy on write呢
還是foreach之初,數組的引用計數並未+1,而是判斷數組做了改變($arr[$k]=111、運行current等函數)的時候才去複製一份數組,開闢新的記憶體空間呢
當然不管怎麼做,對代碼的執行結果似乎都是一樣的
不過準備整理文檔和大家分享下,以免誤導
這裡先謝謝諸位了
回複內容:
PHP中的foreach
如果數組的is_ref為1,則直接迴圈原數組
如果foreach($arr as &$v){}最終會把$arr的is_ref設為1,直接迴圈原數組
如果數組is_ref為0,但引用計數大於1,會拷貝數組,並開闢新的記憶體空間,迴圈被拷貝的數組
以上說的有沒有問題呢?
還有比較糾結的一個問題
在foreach之初,就把數組的引用計數+1呢,然後數組改變的時候,$arr[$k]=111或者運行current等函數,copy on write呢
還是foreach之初,數組的引用計數並未+1,而是判斷數組做了改變($arr[$k]=111、運行current等函數)的時候才去複製一份數組,開闢新的記憶體空間呢
當然不管怎麼做,對代碼的執行結果似乎都是一樣的
不過準備整理文檔和大家分享下,以免誤導
這裡先謝謝諸位了
解決:http://segmentfault.com/a/1190000004340640
你說得好亂呀……問題在哪都好難尋覓……
你說的 is_ref 是在 zval 定義裡的 is_ref 嗎?
找到裡的兩個問題,貌似都和 zval 的 copy on write 有關,我簡單回答一下 copy on write 機制把。(這裡基於 PHP 5 , 在 PHP 7 zval 結構變化很大,另當別論)
推變數增加 refcount 就表示有更多的變數使用了這個值,比如 foreach 裡的數組,如果增加 refcount 到 2 ,就表示值裡的 zval.value 裡的 HashTable 被使用在兩個變數中,這時候覆制並不是馬上發生。而是在修改變數的時候,如果檢測到 refcount > 1 (表示有其他變數引用了這個 HashTable),就要先把 HashTable 複製一份,在進行修改。
應該指明版本 7改了,為了避免麻煩 我盡量用array walk