主頁(yè) > 知識(shí)庫(kù) > PHP關(guān)于foreach復(fù)制知識(shí)點(diǎn)總結(jié)

PHP關(guān)于foreach復(fù)制知識(shí)點(diǎn)總結(jié)

熱門(mén)標(biāo)簽:地圖標(biāo)注怎么做商戶驗(yàn)證 亳州企業(yè)外呼系統(tǒng) 蘇州外呼系統(tǒng)有效果嗎 兼職做地圖標(biāo)注好賺錢(qián)嗎 智能電銷(xiāo)語(yǔ)音機(jī)器人資訊 400 電話 辦理 海南外呼系統(tǒng)方案 打開(kāi)百度地圖標(biāo)注 山東電銷(xiāo)卡外呼系統(tǒng)原理是什么

PHP的foreach是一個(gè)非常整潔和切中要害的語(yǔ)言結(jié)構(gòu)。仍然有些人不喜歡使用它,因?yàn)樗麄冋J(rèn)為它是緩慢的。一個(gè)通常命名的原因是foreach復(fù)制它迭代的數(shù)組。

因此,一些人建議寫(xiě):

$keys = array_keys($array);
$size = count($array);
for ($i = 0; $i  $size; $i++) {
  $key  = $keys[$i];
  $value = $array[$key];
 
  // ...
}

而不是更直觀和直接:

foreach ($array as $key => $value) {
  // ...
}

這里有兩個(gè)問(wèn)題:

Microoptimization是不好的。通常,它只會(huì)浪費(fèi)您的時(shí)間,不會(huì)帶來(lái)任何可度量的性能改進(jìn)。

foreach的復(fù)制行為比大多數(shù)人認(rèn)為的要復(fù)雜一些。通常情況下,“優(yōu)化”的版本會(huì)比原始版本慢。

foreach什么時(shí)候復(fù)制?

foreach是否復(fù)制數(shù)組以及復(fù)制的數(shù)量取決于三件事:

是否引用了迭代數(shù)組、它的refcount有多高以及迭代是否通過(guò)引用完成。

沒(méi)有引用,refcount == 1

在下面的代碼中,$array沒(méi)有被引用,并且refcount為1。在這種情況下,foreach不會(huì)復(fù)制數(shù)組(證明)——這與流行的觀點(diǎn)相反,即foreach總是復(fù)制沒(méi)有引用的迭代數(shù)組。

test();
function test() {
  $array = range(0, 100000);
  foreach ($array as $key => $value) {
    // ...
  }
}

原因很簡(jiǎn)單:為什么要這樣做?foreach修改$array的唯一地方是它是內(nèi)部數(shù)組指針。這是預(yù)期的行為,因此不需要預(yù)防。

未引用,refcount > 1

下面的代碼看起來(lái)非常類似于前面的代碼。唯一的區(qū)別是數(shù)組現(xiàn)在作為參數(shù)傳遞。這似乎是一個(gè)無(wú)關(guān)緊要的區(qū)別,但它確實(shí)改變了foreach的行為:

它現(xiàn)在將復(fù)制數(shù)組結(jié)構(gòu),而不是值(證明;如果你想知道這只是復(fù)制的結(jié)構(gòu),比較一下這個(gè)和那個(gè)腳本。第一個(gè)只復(fù)制結(jié)構(gòu),第二個(gè)兩個(gè)都復(fù)制)。

$array = range(0, 100000);
test($array);
function test($array) {
  foreach ($array as $key => $value) {
    // ...
  }
}

乍一看這可能有點(diǎn)奇怪:

為什么當(dāng)數(shù)組通過(guò)參數(shù)傳遞時(shí),它會(huì)復(fù)制,但如果它是在函數(shù)中定義的,它就不會(huì)復(fù)制了?原因是數(shù)組zval現(xiàn)在在多個(gè)變量之間共享:函數(shù)外部的$array變量和函數(shù)內(nèi)部的$array變量。如果foreach在不復(fù)制數(shù)組結(jié)構(gòu)的情況下迭代數(shù)組,那么它不僅會(huì)改變函數(shù)中$array變量的數(shù)組指針,還會(huì)改變函數(shù)外$array變量的指針。因此foreach需要復(fù)制數(shù)組結(jié)構(gòu)(即散列表)。另一方面,這些值仍然可以共享zvals,因此不需要復(fù)制。

引用

下一種情況與前一種情況非常相似。唯一的區(qū)別是數(shù)組是通過(guò)引用傳遞的。在這種情況下,數(shù)組將不會(huì)被復(fù)制(證明)。

$array = range(0, 100000);
test($array);
function test($array) {
  foreach ($array as $key => $value) {
    // ...
  }
}

在這種情況下,相同的推理適用于前一種情況:外部$數(shù)組和內(nèi)部$數(shù)組共享zvals。不同的是,它們現(xiàn)在是引用(isref == 1),因此在這種情況下,對(duì)內(nèi)部數(shù)組的任何更改都將對(duì)外部數(shù)組進(jìn)行。所以如果內(nèi)部數(shù)組的數(shù)組指針改變了,外部數(shù)組的數(shù)組指針也應(yīng)該改變。這就是foreach不需要復(fù)制的原因。

迭代通過(guò)引用

上面的例子都是按值迭代的。對(duì)于引用迭代,應(yīng)用相同的規(guī)則,但是附加值引用更改數(shù)組值的復(fù)制行為(關(guān)于結(jié)構(gòu)復(fù)制的行為保持不變)。

情況“未引用,refcount == 1”沒(méi)有改變。引用迭代意味著如果$值有任何變化,我們想要改變?cè)紨?shù)組,這樣數(shù)組就不會(huì)被復(fù)制(證明)。

“被引用”的情況也保持不變,在這種情況下,對(duì)$value的更改應(yīng)該會(huì)更改引用迭代數(shù)組的所有變量(證明)。

只有“未引用,refcount > 1”的情況發(fā)生了變化,因?yàn)楝F(xiàn)在需要復(fù)制數(shù)組結(jié)構(gòu)及其值。數(shù)組結(jié)構(gòu),因?yàn)榉駝t函數(shù)外部的$array變量的數(shù)組指針會(huì)改變,而對(duì)$value的改變也會(huì)改變外部的$array值(證明)。

總結(jié)

當(dāng)且僅當(dāng)?shù)鷶?shù)組未被引用且具有refcount > 1時(shí),foreach將復(fù)制數(shù)組結(jié)構(gòu)

foreach還將復(fù)制數(shù)組值,前提是且僅當(dāng)上一個(gè)點(diǎn)應(yīng)用并且迭代是通過(guò)引用完成時(shí)

您可能感興趣的文章:
  • 在PHP中靈活使用foreach+list處理多維數(shù)組的方法
  • vue.js 雙層嵌套for遍歷的方法詳解, 類似php foreach()
  • PHP運(yùn)用foreach神奇的轉(zhuǎn)換數(shù)組(實(shí)例講解)
  • PHP在彈框中獲取foreach中遍歷的id值并傳遞給地址欄
  • php優(yōu)化查詢foreach代碼實(shí)例講解

標(biāo)簽:呼倫貝爾 紹興 溫州 安康 萊蕪 綏化 金華 清遠(yuǎn)

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《PHP關(guān)于foreach復(fù)制知識(shí)點(diǎn)總結(jié)》,本文關(guān)鍵詞  PHP,關(guān)于,foreach,復(fù)制,知識(shí)點(diǎn),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《PHP關(guān)于foreach復(fù)制知識(shí)點(diǎn)總結(jié)》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于PHP關(guān)于foreach復(fù)制知識(shí)點(diǎn)總結(jié)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章