亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在PHP中使用foreach

發布時間:2021-06-01 16:36:53 來源:億速云 閱讀:142 作者:Leah 欄目:編程語言

今天就跟大家聊聊有關如何在PHP中使用foreach,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

語言基礎

foreach 語法結構提供了遍歷數組的簡單方式。

php5之前, foreach僅能用于數組 php5+, 利用foreach可以遍歷對象

foreach僅能夠應用于數據和對象,如果嘗試應用于其他數據類型的變量,或者未初始化的變量將發出錯誤信息。

有兩種語法:

/*
  遍歷給定的 array_expression 數據。每次循環中, 當前單元的值被賦給$value并且數組內部的指針向前移一步(因此下次循環中將會得到下一個單元)
*/
foreach (array_expression as $value) {
    // statement
}

foreach (array_expression as $value) :
    // statement
endforeach;
/*
  同上,只除了當前單元格的鍵名也會在每次循環中被賦給變量$key
*/
foreach (array_expression as $key => $value) {
    // statement
}

foreach (array_expression as $key => $value) :
    // statement
endforeach;

還能夠自定義遍歷對象!

foreach開始執行時, 數組內部的指針會自動指向第一個單元. 這意味著不需要在foreach循環之前調用reset()由于foreach依賴內部數組指針, 在循環中修改其值將可能導致意外的行為

可以很容易通過在 $value 之前加上 & 來修改數組元素. 此方法將以引用 賦值, 而不是拷貝一個值.

<?php

$arr = [1, 2, 3, 4];
foreach($arr as &$value) {
    $value = $value * 2;
}

// $arr is now [2, 4, 6, 8]
unset($value); // 最后取消掉引用

$value的引用僅在被遍歷的數組可以被引用時才可用(例如是個變量)。

以下代碼無法運行:

<?php
/*
  此段代碼可以運行
  運行結果:
    1-2
    2-4
    3-6
    4-8
*/
foreach (array(1, 2, 3, 4) as &$value) {
    echo $value, '-';
    $value = $value * 2;
    echo $value, PHP_EOL;
}

Warning: 數組最后一個元素的 $value 引用在 foreach 循環之后仍會保留。建議使用 unset() 來將其銷毀。

Note: foreach 不支持用 @ 來抑制錯誤信息的能力

foreach 雖然簡單, 不過它可能出現一些意外行為, 特別是代碼涉及到引用的時候。

問題研究

問題一: 如下代碼運行結果為何不是 2/4/6 ?

<?php
$arr = [1, 2, 3];

foreach ($arr as $k => &$v) {
    $v = $v * 2;
}

foreach ($arr as $k => $v) {
    echo $v, PHP_EOL;
}

/*
輸出:
    2
    4
    4
*/

我們可以認為 foreach($arr as &$v) 結構隱含了如下操作, 分別將數組當前的 賦值給 $k$v. 具體展開形如:

<?php
foreach ($arr as $k => $v) {
    $k = currentKey();
    $v = currentVal();
    // 繼續運行用戶代碼
}

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

循環備注$arr值
循環 1-1由于$v是一個引用, 因此 $v = &$arr[0], $v = $v * 2 相當于 $arr[0] * 2[2, 2, 3]
循環 1-2$v = &$arr[1][2, 4, 3]
循環 1-3$v = &$arr[2][2, 4, 6]
循環 2-1隱含操作 $v = $arr[0] 被觸發, 由于此時 $v 仍是 $arr[2] 的引用, 相當于 $arr[2] = $arr[0][2, 4, 2]
循環 2-2$v = $arr[1], 即$arr[2] = $arr[1][2, 4, 4]
循環 2-3$v = $arr[2], 即$arr[2] = $arr[2][2, 4, 4]

如何解決此類問題呢? PHP手冊上有一段提醒:

Warning: 數組最后一個元素的 $value 引用在 foreach 循環之后仍會保留。建議使用 unset() 來將其銷毀。

<?php
$arr = [1, 2, 3];

foreach ($arr as $k => &$v) {
    $v = $v * 2;
}
unset($v);
foreach ($arr as $k => $v) {
    echo $v, PHP_EOL;
}

/*
輸出:
    2
    4
    6
*/

從這個問題可以看出, 引用很可能會伴隨副作用。如果不希望無意識的修改導致數據內容變更, 最好及時unset掉這些引用。

問題二: 如下代碼運行結果為何不是 0=>a 1=>b 2=>c

<?php
$arr = ['a', 'b', 'c'];

foreach ($arr as $k => $v) {
    echo key($arr), "=>", current($arr), PHP_EOL;
}

foreach ($arr as $k => &$v) {
    echo key($arr), "=>", current($arr), PHP_EOL;
}
/*
#php5.6
1=>b 1=>b 1=>b
1=>b 2=>c =>

#php7
0=>a 0=>a 0=>a
0=>a 0=>a 0=>a
*/

按照手冊中的說法, key和current分別是獲取數據中當前元素的鍵值。 那為何 key($arr) 一直是0,current($arr) 一直是'a'呢?

先用vld查看編譯后的 opcode:

?  demo /usr/local/Cellar/php/7.2.7/bin/php -dvld.active=1 a.php
Finding entry points
Branch analysis from position: 0
Jump found. (Code = 77) Position 1 = 2, Position 2 = 15
Branch analysis from position: 2
Jump found. (Code = 78) Position 1 = 3, Position 2 = 15
Branch analysis from position: 3
Jump found. (Code = 42) Position 1 = 2
Branch analysis from position: 2
Branch analysis from position: 15
Jump found. (Code = 62) Position 1 = -2
Branch analysis from position: 15
filename:       /Users/jianyong/demo/a.php
function name:  (null)
number of ops:  17
compiled vars:  !0 = $arr, !1 = $v, !2 = $k
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   ASSIGN                                                   !0, <array>
   4     1      > FE_RESET_R                                       $4      !0, ->15
         2    > > FE_FETCH_R                                       ~5      $4, !1, ->15
         3    >   ASSIGN                                                   !2, ~5
   5     4        INIT_FCALL                                               'key'
         5        SEND_VAR                                                 !0
         6        DO_ICALL                                         $7
         7        ECHO                                                     $7
         8        ECHO                                                     '%3D%3E'
         9        INIT_FCALL                                               'current'
        10        SEND_VAR                                                 !0
        11        DO_ICALL                                         $8
        12        ECHO                                                     $8
        13        ECHO                                                     '%0A'
        14      > JMP                                                      ->2
        15    >   FE_FREE                                                  $4
   7    16      > RETURN                                                   1

branch: #  0; line:     2-    4; sop:     0; eop:     1; out1:   2; out2:  15
branch: #  2; line:     4-    4; sop:     2; eop:     2; out1:   3; out2:  15
branch: #  3; line:     4-    5; sop:     3; eop:    14; out1:   2
branch: # 15; line:     5-    7; sop:    15; eop:    16; out1:  -2
path #1: 0, 2, 3, 2, 15,
path #2: 0, 2, 15,
path #3: 0, 15,
0=>a
0=>a
0=>a

PHP7新特性之foreach

  • [x] foreach 循環對數組內部指針不再起作用, 在PHP7之前, 當數據通過foreach迭代時, 數組指針會移動。

<?php
$array = [0, 1, 2];
foreach ($array as &$val) {
    var_dump(current($array));
}
版本結果說明
PHP5int(1) int(2) bool(false)數組指針會移動
PHP7int(0) int(0) int(0)數據指針不再移動
  • [x] 按照值進行循環時, 對數組的修改是不會影響循環。

foreach按照值進行循環的時候(by-value), foreach是對該數組的一個拷貝進行操作. 所以在循環過程中修改不影響循環結果

<?php
$arr = [0, 1, 2];
$ref = &$arr;

foreach ($arr as $val) {
    var_dump($val);
    unset($arr[1]);
}
版本結果說明
PHP5int(0) int(2)會將unset的數據跳過
PHP7int(0) int(1) int(2)對數組的改動不影響循環
  • [x] 按照引用進行循環的時候, 對數組的修改會影響循環

<?php
$arr = [0, 1, 2];
$ref = &$arr;

foreach ($arr as &$val) {
    var_dump($val);
    unset($arr[1]);
}
版本結果
PHP5int(0) int(2)
PHP7int(0) int(2)
  • [x] 對簡單對象plain(non-Traversable)的循環

在簡單對象的循環, 不管是按照值循環還是引用循環, 和按照引用對數組循環的行為是一樣的, 不過對位置的管理會更加精確

  • [x] 對迭代對象(Traversable objects)對象行為和之前一致

stackoverflow 上面的解釋, Traversable objects is one that implements Iterator or IteratorAggregate interface

如果一個對象實現了 Iterator 或者 IteratorAggregate 接口, 即可稱之為迭代對象

看完上述內容,你們對如何在PHP中使用foreach有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

普宁市| 楚雄市| 桃江县| 石台县| 若尔盖县| 天峻县| 鸡东县| 永吉县| 尉氏县| 万山特区| 东源县| 额尔古纳市| 开江县| 南平市| 邯郸市| 唐河县| 开原市| 石棉县| 南京市| 贡觉县| 沈阳市| 通渭县| 三明市| 高唐县| 巧家县| 香格里拉县| 宣恩县| 阳山县| 榆中县| 鹤岗市| 卢湾区| 柘城县| 建阳市| 浠水县| 舟山市| 云南省| 方城县| 永康市| 精河县| 北碚区| 西峡县|