首頁 後端開發 php教程 PHP foreach何時複製

PHP foreach何時複製

Jan 28, 2019 am 11:53 AM

本文描述了PHP 5中foreach的複製行為。需要一些PHP內部工作原理的知識,即zvals, refcount和copy-on-write行為。

PHP foreach何時複製

PHP的foreach是一個非常整齊和切中要害的語言結構。仍然有些人不喜歡使用它,因為他們認為它是緩慢的。一個通常命名的原因是foreach複製它迭代的數組。

因此,有些人建議寫:

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

    // ...
}
登入後複製

而不是更直觀和直接:

foreach ($array as $key => $value) {
    // ...
}
登入後複製

這裡有兩個問題:

##Microoptimization是不好的。通常,它只會浪費您的時間,不會帶來任何可度量的效能改進。

foreach的複製行為比大多數人認為的要複雜一些。通常情況下,「優化」的版本會比原始版本慢。

foreach什麼時候複製?

foreach是否複製數組以及複製的數量取決於三件事:

是否引用了迭代數組、它的refcount有多高以及迭代是否透過引用完成。

沒有引用,refcount == 1

在下面的程式碼中,$array沒有被引用,且refcount為1。在這種情況下,foreach不會複製數組(證明)——這與流行的觀點相反,即foreach總是複製沒有引用的迭代數組。

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

原因很簡單:為什麼要這樣做?foreach修改$array的唯一地方是它是內部陣列指標。這是預期的行為,因此不需要預防。

未引用,refcount > 1

下面的程式碼看起來非常類似前面的程式碼。唯一的區別是數組現在作為參數傳遞。這似乎是一個無關緊要的區別,但它確實改變了foreach的行為:

它現在將複製數組結構,而不是值(證明;如果你想知道這只是複製的結構,比較這個和那個腳本。第一個只複製結構,第二個兩個都複製)。

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

乍看之下這可能有點奇怪:

為什麼當陣列通過參數傳遞時,它會複製,但如果它是在函數中定義的,它就不會複製了?原因是數組zval現在在多個變數之間共享:函數外部的$array變數和函數內部的$array變數。如果foreach在不複製數組結構的情況下迭代數組,那麼它不僅會改變函數中$array變數的數組指針,還會改變函數外$array變數的指針。因此foreach需要複製數組結構(即散列表)。另一方面,這些值仍然可以共享zvals,因此不需要複製。

引用

下一個情況與前一個情況非常相似。唯一的區別是數組是透過引用傳遞的。在這種情況下,數組將不會被複製(證明)。

$array = range(0, 100000);
test($array);
function test(&$array) {
    foreach ($array as $key => $value) {
        // ...
    }
}
登入後複製
在這種情況下,相同的推理適用於前一種情況:外部$數組和內部$數組共享zvals。不同的是,它們現在是引用(isref == 1),因此在這種情況下,對內部數組的任何更改都將對外部數組進行。所以如果內部數組的數組指標改變了,外部數組的數組指標也應該改變。這就是foreach不需要複製的原因。

迭代透過引用

上面的範例都是按值迭代的。對於引用迭代,應用相同的規則,但是附加值引用更改數組值的複製行為(關於結構複製的行為保持不變)。

情況「未引用,refcount == 1」沒有改變。引用迭代意味著如果$值有任何變化,我們想要改變原始數組,這樣數組就不會被複製(證明)。

「被引用」的情況也保持不變,在這種情況下,對$value的更改應該會更改引用迭代數組的所有變數(證明)。

只有「未引用,refcount > 1」的情況發生了變化,因為現在需要複製陣列結構及其值。陣列結構,因為否則函數外部的$array變數的陣列指標會改變,而對$value的改變也會改變外部的$array值(證明)。

總結

當且僅當迭代數組未被引用且具有refcount > 1時,foreach將複製數組結構

foreach也將複製數組值,前提是且僅當上一個點應用並且迭代是透過引用完成時

以上是PHP foreach何時複製的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

解釋PHP中晚期靜態結合的概念。 解釋PHP中晚期靜態結合的概念。 Mar 21, 2025 pm 01:33 PM

文章討論了PHP 5.3中介紹的PHP中的晚期靜態結合(LSB),允許靜態方法的運行時間分辨率調用以更靈活的繼承。 LSB的實用應用和潛在的觸摸

框架安全功能:防止漏洞。 框架安全功能:防止漏洞。 Mar 28, 2025 pm 05:11 PM

文章討論了框架中的基本安全功能,以防止漏洞,包括輸入驗證,身份驗證和常規更新。

自定義/擴展框架:如何添加自定義功能。 自定義/擴展框架:如何添加自定義功能。 Mar 28, 2025 pm 05:12 PM

本文討論了將自定義功能添加到框架上,專注於理解體系結構,識別擴展點以及集成和調試的最佳實踐。

如何用PHP的cURL庫發送包含JSON數據的POST請求? 如何用PHP的cURL庫發送包含JSON數據的POST請求? Apr 01, 2025 pm 03:12 PM

使用PHP的cURL庫發送JSON數據在PHP開發中,經常需要與外部API進行交互,其中一種常見的方式是使用cURL庫發送POST�...

描述紮實的原則及其如何應用於PHP的開發。 描述紮實的原則及其如何應用於PHP的開發。 Apr 03, 2025 am 12:04 AM

SOLID原則在PHP開發中的應用包括:1.單一職責原則(SRP):每個類只負責一個功能。 2.開閉原則(OCP):通過擴展而非修改實現變化。 3.里氏替換原則(LSP):子類可替換基類而不影響程序正確性。 4.接口隔離原則(ISP):使用細粒度接口避免依賴不使用的方法。 5.依賴倒置原則(DIP):高低層次模塊都依賴於抽象,通過依賴注入實現。

ReactPHP的非阻塞特性究竟是什麼?如何處理其阻塞I/O操作? ReactPHP的非阻塞特性究竟是什麼?如何處理其阻塞I/O操作? Apr 01, 2025 pm 03:09 PM

深入解讀ReactPHP的非阻塞特性ReactPHP的一段官方介紹引起了不少開發者的疑問:“ReactPHPisnon-blockingbydefault....

See all articles