鍍金池/ 問答/PHP/ PHP5和PHP7 foreach循環(huán)問題

PHP5和PHP7 foreach循環(huán)問題

PHP7 升級手冊中提及了"foreach 通過值遍歷時(shí),操作的值為數(shù)組的副本. 當(dāng)默認(rèn)使用通過值遍歷數(shù)組時(shí),foreach 實(shí)際操作的是數(shù)組的迭代副本,而非數(shù)組本身。這就意味著,foreach 中的操作不會(huì)修改原數(shù)組的值。" 我以為PHP5的foreach循環(huán)是數(shù)組本身, 于是驗(yàn)證一下, 結(jié)果跟我想的不一樣. 但是我查詢資料時(shí)候看到一個(gè)代碼, 讓我感覺有所疑惑. 麻煩解答一下我疑惑

$array = array('a', 'b', 'c');
$ref = &$array;
foreach ($array as $val) {
    $array[3] = 'd';
    print_r($array);
    echo '迭代的值: ' . $val . "\n";
}

PHP7輸出的結(jié)果:

clipboard.png

PHP5輸出結(jié)果:

clipboard.png

只是把數(shù)組引用一下, 為什么會(huì)出現(xiàn)不一樣結(jié)果? 去掉引用, PHP7和PHP5結(jié)果是一樣的, 到底PHP5中foreach循環(huán)操作數(shù)組是數(shù)組本身還是數(shù)組的副本?

回答
編輯回答
別傷我

研究一個(gè)晚上, 大概懂了一些. 總體上來說, PHP 5 在foreach通過值遍歷時(shí)還是會(huì)拷貝數(shù)組的. 但是PHP 7 內(nèi)部實(shí)現(xiàn)這個(gè)迭代數(shù)組與 PHP 5 不同.PHP 7 不在依靠數(shù)組內(nèi)部指針, 而PHP5是靠內(nèi)部指針的. 驗(yàn)證PHP 5 在foreach下是否拷貝了數(shù)組

$arr = [0];
foreach ($arr as $k => $v) {
    debug_zval_dump($arr);
}

打印出來的refcount為3, 說明在foreach中拷貝數(shù)組了, 導(dǎo)致refcount為3. 進(jìn)一步驗(yàn)證.

$arr = [0];
foreach ($arr as $v) {
    $copy = $arr;
    debug_zval_dump($arr);
}

假設(shè)數(shù)組在循環(huán)中拷貝了, 那么refcount應(yīng)該為4. 其打印結(jié)果跟我猜想一樣. 說明數(shù)組在foreach進(jìn)行拷貝了. 而且不受數(shù)組的長度影響. 因?yàn)閿?shù)組長度為2時(shí)候, 還是打印4.在PHP5 foreach靠的是數(shù)組指針在移動(dòng)從而達(dá)到迭代數(shù)組的值.

$arr = [0, 1];
foreach ($arr as $v) {
    $copy = $arr;
    debug_zval_dump($arr);
}

foreach是如何運(yùn)行的

深入理解PHP原理之變量分離/引用(Variables Separation)

當(dāng)我們使用foreach時(shí),內(nèi)部究竟發(fā)生了什么(PHP5)?

2017年8月5日 10:52