PHP foreach的兩種用法

2021-07-31 09:53:06 字數 2086 閱讀 9751

前言:

php4中引入了foreach結構,這是一種遍歷陣列的簡單方式。相比傳統的for迴圈,foreach能夠更加便捷的獲取鍵值對。在php5之前,foreach僅能用於陣列;php5之後,利用foreach還能遍歷物件。本文中僅討論遍歷陣列的情況。

第一種格式遍歷給定的 array_expression 陣列。

每次迴圈中,當前單元的值被賦給 $value 並且陣列內部的指標向前移一步(因此下一次迴圈中將會得到下乙個單元)。

第二種格式做同樣的事,只是除了當前單元的值以外,鍵值也會在每次迴圈中被賦給變數 $key。看下面**:

鍵值這裡可以理解為陣列下標,陣列元素a[2]的下標就是2.

當 foreach 開始執行時,陣列內部的指標會自動指向第乙個單元。這意味著不需要在 foreach 迴圈之前呼叫 reset()。而while迴圈需要reset。下面兩種**功能完全相同。

1.用while迴圈

2.用foreach

此外注意 foreach 所操作的是指定陣列的乙個拷貝,而不是該陣列本身。因此即使有 each() 的構造,原陣列指標也沒有變,陣列單元的值也不受影響。

foreach 不支援用「@」來禁止錯誤資訊的能力。

foreach雖然簡單,不過它可能會出現一些意外的行為,特別是**涉及引用的情況下。

問題:

複製**

**如下:

$arr = array(1,2,3);

foreach($arr as $k => &$v)

// now $arr is array(2, 4, 6)

foreach($arr as $k => $v)

先從簡單的開始,如果我們嘗試執行上述**,就會發現最後輸出為0=>2  1=>4  2=>4 。

為何不是0=>2  1=>4  2=>6 ?

其實,我們可以認為 foreach($arr as $k => $v) 結構隱含了如下操作,分別將陣列當前的'鍵'和當前的'值'賦給變數$k和$v。具體展開形如:

複製**

**如下:

foreach($arr as $k => $v)

根據上述理論,現在我們重新來分析下第乙個foreach:

第1遍迴圈,由於$v是乙個引用,因此$v = &$arr[0],$v=$v*2相當於$arr[0]*2,因此$arr變成2,2,3

第2遍迴圈,$v = &$arr[1],$arr變成2,4,3

第3遍迴圈,$v = &$arr[2],$arr變成2,4,6

隨後**進入了第二個foreach:

第1遍迴圈,隱含操作$v=$arr[0]被觸發,由於此時$v仍然是$arr[2]的引用,即相當於$arr[2]=$arr[0],$arr變成2,4,2

第2遍迴圈,$v=$arr[1],即$arr[2]=$arr[1],$arr變成2,4,4

第3遍迴圈,$v=$arr[2],即$arr[2]=$arr[2],$arr變成2,4,4

ok,分析完畢。

warning : 陣列最後乙個元素的 $value 引用在 foreach 迴圈之後仍會保留。建議使用unset()來將其銷毀。

複製**

**如下:

$arr = array(1,2,3);

foreach($arr as $k => &$v)

unset($v);

foreach($arr as $k => $v)

// 輸出 0=>2  1=>4  2=>6

從這個問題中我們可以看出,引用很有可能會伴隨***。如果不希望無意識的修改導致陣列內容變更,最好及時unset掉這些引用。

FIELD SYMBOLS的兩種用法

第一種,把fs當做乙個泛型,什麼東西都可以放進去 data begin of man,name type str,20 type c,height type i,end of man.data a man like man.a man name 阿勇 a man f a man height 171...

Android Intent的兩種用法

intent是android元件之一,是用於連線四大元件的乙個比較重要的部分。intent有兩種用法 一種是顯式intent,如果用於啟用activity就這樣寫 intent intent new intent this,testactivity.class startactivity 一種是隱式...

Handler的兩種用法

android 為了執行緒安全,只允許在主線程中修改ui,如果想在子執行緒中更改ui,可以使用handler.用法一 在子執行緒中傳送更新資訊 message msg message.obtain msg.what 1 bundle data new bundle data.putstring so...