成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

PHP 循環(huán)中「引用」引發(fā)的奇怪問題

Riddler / 534人閱讀

摘要:本文整理自網(wǎng)站上的一篇文章在循環(huán)中,如果使用引用會引發(fā)非常奇怪的行為這是的一個嗎問題在我寫一個簡單的腳本時,發(fā)生了一些非常奇怪的現(xiàn)象。在中,如果一個內(nèi)存空間是被引用的,那么當(dāng)改變它的時候是直接改變這塊內(nèi)存空間的值。

本文整理自 stackoverflow 網(wǎng)站上的一篇文章 Strange behaviour after loop by reference - Is this a PHP bug? —— 在 PHP 循環(huán)中,如果使用 引用 會引發(fā)非常奇怪的行為 - 這是 PHP 的一個 bug 嗎?

問題

在我寫一個簡單的 PHP 腳本時,發(fā)生了一些非常奇怪的現(xiàn)象。下面是我的代碼,為了清楚的表達(dá)我的意思,我特意去掉了一些不必要的代碼:



輸出如下:

Array
(
    [0] => foo
    [1] => bar
    [2] => baz
)
Array
(
    [0] => foo
    [1] => bar
    [2] => bar  // 錯誤發(fā)生??
)

這是 PHP 的一個 bug 嗎?PHP 中為什么會發(fā)生如此古怪的行為呢?

解析

在第一個 foreach 循環(huán)結(jié)束后,$item 仍然引用(reference)著數(shù)組的最后一個元素,也就是 $arr[2]。 因此,當(dāng)開始第二個循環(huán)的時候,$item 變量每次循環(huán)都會被賦一個新值。 在 php 中,如果一個內(nèi)存空間是被引用的,那么當(dāng)改變它的時候是直接改變這塊內(nèi)存空間的值。 當(dāng)改變 $item 的時候,其實也改變了 $arr[2] 的值。

因此,在第二個循環(huán)中:

第一次循環(huán),$item$arr[2] 的值變成 $arr[0],也就是 "foo"。

第二次循環(huán),$item$arr[2] 的值變成 $arr[1],也就是 "bar"。

第三次循環(huán),$item$arr[2] 的值變成 $arr[2],也就是 "bar"($arr[2] 的值不是 "baz",因為在第二次循環(huán)中變成了 "bar")。

"baz" 的值實際是在第二個循環(huán)中丟失了。

譯注:我不喜歡把 reference 翻譯成「引用」,當(dāng)然了,更不能翻譯成「參考」了。每次我像別人解釋 reference 時,都會告訴他: reference 就是 alias。 比如你叫吳毅昌(呵呵,無異常),二狗子是你的別名。本著好兄弟好基友的情誼:“來,二狗子,這 100 塊錢給你吧?!?你——吳毅昌——回家一模口袋,多了 100 塊錢。 @justjavac

調(diào)試輸出

我們可以修改代碼來調(diào)試并跟蹤循環(huán)的執(zhí)行細(xì)節(jié)。 我們可以輸出 $item 的值,并且遞歸的輸出數(shù)組 $arr。

當(dāng)?shù)谝粋€循環(huán)運行時,我們可以看到這樣的輸出:

foo
Array ( [0] => foo [1] => bar [2] => baz )

bar
Array ( [0] => foo [1] => bar [2] => baz )

baz
Array ( [0] => foo [1] => bar [2] => baz )

在循環(huán)結(jié)束后,$item$arr[2] 指向同一個內(nèi)存區(qū)域。

當(dāng)?shù)诙€循環(huán)運行時,我們看到這樣的輸出:

foo
Array ( [0] => foo [1] => bar [2] => foo )

bar
Array ( [0] => foo [1] => bar [2] => bar )

bar
Array ( [0] => foo [1] => bar [2] => bar )

在這次循環(huán)中,需要注意隨著每次 $item 被賦予一個新值, $arr[2] 也會被賦值為和 $item 相同的值,因為它們都仍然指向相同的內(nèi)存空間(譯注:原文寫的是 $arr[3],疑為原作者筆誤。@justjavac)。 當(dāng)循環(huán)到達(dá)數(shù)組的第三個值時,它包含的值是 bar,因為它的值在前兩次循環(huán)中,被修改了。

還有疑問

也許你覺得,我僅僅是執(zhí)行了一個空循環(huán) foreach ($arr as &$item){},循環(huán)體里面什么都沒有做,為什么數(shù)組元素卻改變了?

可能你覺得這個代碼應(yīng)該等價于

for ($i = 0; $i < count($arr); $i++) { 
    // do nothing
}

其實不對,代碼應(yīng)該等價于:

for ($i = 0; $i < count($arr); $i++) { 
    $item = $arr[$i]; 
}

也就是說, 在 foreach 循環(huán)中,隱含了一個賦值運算,唯一不同的時, 在賦值過程中,我們使用了引用,所以在第一個循環(huán)中,無意中修改了正在循環(huán)的數(shù)組內(nèi)部的元素。

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

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/20609.html

相關(guān)文章

  • PHP 「自增、自減」運算引發(fā)奇怪問題

    摘要:在的官方手冊中寫道支持風(fēng)格的前后遞增與遞減運算符。第一個注意事遞增遞減運算符不影響布爾值。遞增遞減布爾值遞增遞減在處理字符變量的算數(shù)運算時,沿襲了的習(xí)慣,而非的。還有一個注意事項遞增遞減其他字符變量則無效,原字符串沒有變化。 在 PHP 的官方手冊中寫道: PHP 支持 C 風(fēng)格的前/后遞增與遞減運算符。 第一個注意事:遞增/遞減運算符不影響布爾值。遞減 NULL 值也沒有...

    madthumb 評論0 收藏0
  • foreach遍歷過程奇怪現(xiàn)象(PHP5)

    摘要:中基礎(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)的文章,屬于同一個大的...

    kgbook 評論0 收藏0
  • php底層原理之垃圾回收機制

    摘要:總結(jié)垃圾回收機制以的引用計數(shù)機制為基礎(chǔ)以前只有該機制同時使用根緩沖區(qū)機制,當(dāng)發(fā)現(xiàn)有存在循環(huán)引用的時,就會把其投入到根緩沖區(qū),當(dāng)根緩沖區(qū)達(dá)到配置文件中的指定數(shù)量后,就會進行垃圾回收,以此解決循環(huán)引用導(dǎo)致的內(nèi)存泄漏問題開始引入該機制 php垃圾回收機制,對于PHPer來說是一個不陌生但是又不是很熟悉的內(nèi)容。那么php是怎么實現(xiàn)對不需要的內(nèi)存進行回收的呢? php變量的內(nèi)部存儲結(jié)構(gòu) 首先還是...

    light 評論0 收藏0
  • 增量部署class文件引發(fā)血案

    摘要:背景項目中通過遠(yuǎn)程調(diào)用服務(wù)框架調(diào)用了許多其它的服務(wù)其中有一個服務(wù)需要升級其升級不是版本上的升級而是整個服務(wù)重新取了一個名字使用的也是全新的包但是調(diào)用的方法沒有改變因此在升級時只是在調(diào)用服務(wù)類中修改了調(diào)用地址和調(diào)用返回實體由改為該中返回該調(diào)用 背景 項目中通過遠(yuǎn)程調(diào)用服務(wù)框架調(diào)用了許多其它的服務(wù),其中有一個服務(wù)wx/subscribe/contract/CircleService 需要升...

    lolomaco 評論0 收藏0
  • 十個 PHP 開發(fā)者最容易犯錯誤

    摘要:這種行為比最初出現(xiàn)的問題更為棘手,同時也是一種常見的錯誤源。這意味著這個數(shù)組的一份拷貝將會被返回,因此被調(diào)函數(shù)與調(diào)用者所訪問的數(shù)組并不是同樣的數(shù)組實例。 showImg(https://segmentfault.com/img/bV7reP?w=620&h=620); PHP 語言讓 WEB 端程序設(shè)計變得簡單,這也是它能流行起來的原因。但也是因為它的簡單,PHP 也慢慢發(fā)展成一個相對...

    fireflow 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<