php:foreach和in_array用法執行個體詳解

來源:互聯網
上載者:User
php在開發效率很高,這是無可厚非的,但是卻是在犧牲執行效率的。php數組功能非常強大,但是也要多加考慮,多試幾種情況情況,以防萬一,這裡,就簡單的說兩個遇到的坑,以後如果有發現更多的,再補上吧!

1. foreach 提供了遍曆數組的簡單方式,可以很方便的讀取到資料或對象的內容,但是官方文檔說了,由於 foreach 依賴內部數組指標,在迴圈中修改其值將可能導致意外的行為。所以,基本上,
1、不要想在迴圈內部修改裡面的值,否則結果將超出你想要的;
2、使用'&'是一個安全的方式,雖然很少用到,但是在用到時,在引用結束後,應立即調用unset函數銷毀該變數,否則,在接下來的代碼裡,如果有再次使用到此變數,那麼迴圈的最後一次值就將被修改了,從而得到了意外的值,比如:在列表迴圈輸出時,最後一行輸出將會出現許多亂七八糟的值或者空值。使用unset可解決此問題。

我們來看個樣本

<?php /*-------------------------------------------------------------------------*/ /* foreach example 1: value only */ echo "foreach example 1: value only ".'<br />'; $a = array(1, 2, 3, 17); foreach ($a as $v) { echo "Current value of ".$a.":". $v."<br />"; } ?> // 運行結果 foreach example 1: value only Current value of $a: 1 Current value of $a: 2 Current value of $a: 3 Current value of $a: 17

2. in_array,其含義是檢查前一個字串是否存在於後一個數組當中,而且大多數情況下,它也是這麼工作的,但是當後面的數組是整數時,如array(0,1,2,3)時,就出問題了,php會將前的字串進行intval,從而都會得到0這個值,那麼如果恰巧,你的數組當中有這個值,那麼等式就成立了,是不是又超出了預期呢?

所以,當確定後面的資料是整數時,尤其是還有可能為0(這個可能代替所有的字串了),你就千萬不能再使用這個函數了,可使用key_exists來代替,但是後面的資料則需要使用array_flip進行倒轉操作了。

我們再來看個樣本

function search($keyWord, $stack) {//此處判斷是應該更新還是插入      foreach ($stack as $key => $val) {        if (in_array($keyWord, $val)) {          return TRUE;        }      }      return FALSE;    }

  當一個字串被當作數組來去取值時,又會發生什麼呢?php是一門容錯性很強的語言,它會盡量幫你改正錯誤,所以很聰明地將你的引用下標轉化為整數,當然就得到0了,那麼字串下標為0取值則又會得到第一個字串的值,是不是又超出了你的預期呢?解決方案是,在引用下標之前,還是確認一下這個變數是不是一個數組吧,is_array。

3. foreach中引用變數遇到的問題

寫PHP好多年,但仍然會犯低級錯誤,今天遇到個 foreach中引用變數時的問題,PHP版本為 5.6.12 代碼如下:

<?php$arr = ['a', 'b', 'c', 'd', 'e'];foreach ($arr as $i=>&$a) {  $a = $a.'_'. $a;  echo $a .'<br>';}echo '<hr>';foreach ($arr as $i=>$a) {  echo $a .'<br>';}echo '<hr>';print_r($arr);

輸出結果

開始看到第二個 foreach 輸出的結果感覺很是莫名其妙,怎麼會輸出兩個 d_d 呢?

仔細想了想,原來因為PHP foreach 中的 $a 的範圍是整個函數的局部變數,在迴圈外部仍然有效,而不是被封閉在迴圈內的,

所以當執行第二個foreach 時的 $a 並不是新的變數,而是仍然指向 $arr 數組第5個元素的地址引用,

當第二個 foreach 在迴圈時實際上是在不停的給 $arr 數組的第5個元素賦值,

具體賦值情況,

第一次:a_a 賦值給第5個元素, 結果為: [a_a, b_b, c_c, d_d,a_a]

第二次:b_b 賦值給第5個元素,結果為: [a_a, b_b, c_c, d_d,b_b]

第三次:c_c 賦值給第5個元素,結果為: [a_a, b_b, c_c, d_d,c_c]

第四次:d_d 賦值給第5個元素,結果為: [a_a, b_b, c_c, d_d,d_d]

第五次:此時因為第五個元素已經變成 d_d 又重新把 d_d 賦值給第5個元素,結果還是為: [a_a, b_b, c_c, d_d,d_d]

解決辦法:

1.盡量不使用相同的迴圈變數名;

2.每次使用完或再次使用前進行 unset($a); 處理,解除地址應用

還是用上面程式碼範例:

$arr = ['a', 'b', 'c', 'd', 'e'];foreach ($arr as $i=>&$a) {  $a = $a.'_'. $a;  echo $a .'<br>';}echo '<hr>';echo $a;echo '<hr>';// 這裡 unset 掉unset($a);echo $a = 'ccc';echo '<hr>';print_r($arr);echo '<hr>';foreach ($arr as $i=>$a) {  echo $a .'<br>';}echo '<hr>';print_r($arr);

輸出結果:

現在就正常了,這些小細節一定要注意了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.