亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

foreach遍歷過程中的奇怪現(xiàn)象(PHP5)

kgbook / 2113人閱讀

摘要:中基礎(chǔ)中的三大坑,遍歷,引用機制,數(shù)組。今天我們在講講中的一些奇怪現(xiàn)象。本文適合有一定基礎(chǔ)的。運行流程共用一個結(jié)構(gòu)體開始遍歷數(shù)組,進行判斷,拷貝數(shù)組是一個新的結(jié)構(gòu)體,操作的是新的結(jié)構(gòu)體。那么遍歷數(shù)組時,全程與原數(shù)組無關(guān)。

PHP中基礎(chǔ)中的三大坑,foreach遍歷,引用機制&,數(shù)組。

今天我們在講講foreach中的一些奇怪現(xiàn)象。

在講解之前,可以先看看我其他相關(guān)的文章,屬于同一個大的知識點,都看看有助于理解。

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

PHP底層分析:關(guān)于寫時復(fù)制(cow)

PHP底層分析:關(guān)于強制分裂

△△△寫前聲明:以下結(jié)論都基于PHP5版本,因為時代在進步,在PHP7中內(nèi)部的結(jié)構(gòu)體模塊和引用模塊均發(fā)生重大變化,PHP7的foreach輸出規(guī)則也旋即發(fā)生變化。當(dāng)然,由于PHP7想要普及還需要一到兩年(今年是2016)時間,所以這篇文章還是有些價值的,至少可以讓你先理解一下PHP內(nèi)部實現(xiàn)。

有疑問可以直接在評論中拋出,我會一一解答。

本文適合有一定基礎(chǔ)的PHPer。

那么開始上圖,這是鳥哥(惠新宸,PHP7核心開發(fā)組成員,開發(fā)組中唯一的一個中國人[撒花])在Think 2015 PHP技術(shù)峰會上的一個演講截圖,他在講述PHP5的foreach和PHP7的foreach區(qū)別,我們把他演講中提及到PHP5的部分拿出來看看。

那么我們著重看下這幅圖的三段代碼執(zhí)行流程。

我講講三段代碼的運行原理

code1.php

 $value) {
    var_dump(current($a));     //output int(2) int(2) int(2)
}
?>

輸出值為: int(2) int(2) int(2)。

同學(xué)們可能納悶了,乍一看并沒有發(fā)生明顯的寫時復(fù)制(相關(guān)文章)或者強制分裂(相關(guān)文章),怎么會是三個"2"呢。

關(guān)鍵點在于current()函數(shù)上:

foreach循環(huán)開始,拷貝一個數(shù)組出來,然后refcount_gc=2(foreach原理不太了解的同學(xué),可以看看我的另一篇文章:當(dāng)我們使用foreach時,內(nèi)部究竟發(fā)生了什么?(PHP5) )

此時原數(shù)組($a)和拷貝數(shù)組(我這里命名為$a_copy)的指針均指向下標(biāo)1,

隨后進入大括號執(zhí)行體,current()操作的參數(shù)必須是引用數(shù)組(紅線部分),如果不是引用數(shù)組的話會強制轉(zhuǎn)換成引用數(shù)組(即結(jié)構(gòu)體中is_ref__gc從0 -> 1)。

根據(jù)強制分裂原理,一個結(jié)構(gòu)體的is_ref__gc的值從0 -> 1的時候,如果refcount_gc=2時,就會發(fā)生url"強制分裂了"。

強制分裂后, 原數(shù)組($a)和拷貝數(shù)組(我這里命名為$a_copy)結(jié)構(gòu)體已經(jīng)不一樣,但是foreach操作的是拷貝數(shù)組($a_copy),原數(shù)組被丟在半道上了,所以三次輸出var_dump(current($a))均為2

code2.php


這段代碼和code1.php原理差不多,只是在foreach前進行了一次引用賦值,結(jié)構(gòu)體變化成:refcount_gc=2;is_ref_gc=1; 隨后foreach遍歷數(shù)組,此時原數(shù)組($a),拷貝數(shù)組(我這里命名為$a_copy)和$b的指針均指向下標(biāo)1并且均為引用數(shù)負(fù)責(zé)(is_ref_gc)。

接著進入大括號執(zhí)行體:var_dump(current($a)); 前面說道",current()操作的參數(shù)必須是引用數(shù)組(紅線部分),如果不是引用數(shù)組的話會強制轉(zhuǎn)換成引用數(shù)組(即結(jié)構(gòu)體中is_ref__gc從0 -> 1)。"

此處參數(shù)$a已經(jīng)為引用數(shù)組,不會發(fā)生強制分裂,原數(shù)組($a)和拷貝數(shù)組($a_copy)為同一個結(jié)構(gòu)體,正常輸入為:int(2) int(3) bool(false)

code3.php

 $value) {
    var_dump(current($a));    //output int(1) int(1) int(1)
}
?>

第三段代碼和前面兩個又有所不同了,這次$b=$a是使用傳值賦值,那么此處為什么為3個int(1)呢?這次的原因在于foreach的機制:

foreach循環(huán)之前,需要判斷數(shù)組的 refcount計數(shù),如果大于1,拷貝數(shù)組自己成為一個新的結(jié)構(gòu)體,循環(huán)過程操作的是新的結(jié)構(gòu)體。

運行流程:
line:3; // $a,$b共用一個結(jié)構(gòu)體

line:4; //foreach開始遍歷數(shù)組,進行refcount判斷,拷貝數(shù)組是一個新的結(jié)構(gòu)體,foreach操作的是新的結(jié)構(gòu)體。那么遍歷數(shù)組時,全程與原數(shù)組無關(guān)。

Line:5: //打印數(shù)組當(dāng)前單元,由于原數(shù)組和拷貝數(shù)組已不是一個結(jié)構(gòu)體,所以原數(shù)組的指針沒變過,打印出int(1)。

如果還是有些不明覺厲的話,可以反復(fù)看多幾遍,對了,再次推薦看下這幾篇文章,都能理解的話對foreach掌握也差不多夠用了。

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

PHP底層分析:關(guān)于寫時復(fù)制(cow)

PHP底層分析:關(guān)于強制分裂

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/30347.html

相關(guān)文章

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

    摘要:如何證明我的說法呢可以用下面這段代碼檢驗。那么在這里我們需要特別注意,為了保險起見我們在遍歷數(shù)組后,最好手動一下數(shù)組,防止出錯這樣就正常了。還有一點手冊也提醒我們了轉(zhuǎn)成代碼的意思就是遍歷后和是真實存在的,最好使用后能手動掉。 以下所有結(jié)論均基于PHP5版本看下面一段最基礎(chǔ)的foreach遍歷數(shù)組代碼。 輸出為’0a1b2c’自然沒有疑問,那么此過程中$arr,$key,$valu...

    paulli3 評論0 收藏0
  • php中Generator的執(zhí)行過程

    摘要:說到中的生成器,有人可能會想到協(xié)程,這里我們先不說如何實現(xiàn)協(xié)程,我們探究下的執(zhí)行過程。如果函數(shù)包含了關(guān)鍵字的,那么函數(shù)執(zhí)行后的返回值永遠都是一個對象。如果函數(shù)內(nèi)部同事包含和該函數(shù)的返回值依然是對象,但是在生成對象時,語句后的代碼被忽略。 說到php中的Generator(生成器),有人可能會想到協(xié)程,這里我們先不說php如何實現(xiàn)協(xié)程,我們探究下Generator的執(zhí)行過程。 Gene...

    Caicloud 評論0 收藏0
  • 深入理解PHP之foreach

    摘要:建議使用來將其銷毀。那為何一直是,一直是呢先用查看編譯后的新特性之循環(huán)對數(shù)組內(nèi)部指針不再起作用在之前當(dāng)數(shù)據(jù)通過迭代時數(shù)組指針會移動。版本結(jié)果說明數(shù)組指針會移動數(shù)據(jù)指針不再移動按照值進行循環(huán)時對數(shù)組的修改是不會影響循環(huán)。 招聘 標(biāo)簽(空格分隔): 招聘 PHP 國貿(mào) 語言基礎(chǔ) foreach 語法結(jié)構(gòu)提供了遍歷數(shù)組的簡單方式。 php5之前, foreach僅能用于數(shù)組php5+, 利...

    Lemon_95 評論0 收藏0
  • JS 數(shù)組循環(huán)遍歷方法的對比

    摘要:循環(huán)方法方法不改變原數(shù)組方法會給原數(shù)組中的每個元素都按順序調(diào)用一次函數(shù)。篩選出過濾出數(shù)組中符合條件的項組成新數(shù)組代碼方法方法為數(shù)組中的每個元素執(zhí)行一次函數(shù),直到它找到一個使返回表示可轉(zhuǎn)換為布爾值的值的元素。 showImg(https://segmentfault.com/img/bV2QTD?w=1600&h=500); 前言 JavaScript 發(fā)展至今已經(jīng)發(fā)展出多種數(shù)組的循環(huán)遍...

    BlackFlagBin 評論0 收藏0
  • For與while時間的對比

    摘要:結(jié)果分析雖然我沒有代碼,但是我猜測是循環(huán)執(zhí)行語句的多少差別。如果有更好的原因可以評論或者發(fā)起后話生命不息,技術(shù)不止。很多時候我也為了代碼量的減少不理會運行時間的差異,這次吸收教訓(xùn),之后在實際開發(fā)會更加注意時間。 ????本文首發(fā)于cartoon的博客????轉(zhuǎn)載請注明出處:https://cartoonyu.github.io/cartoon-blog/post/java/for%E4...

    lcodecorex 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<