首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 陣列遍歷完全指南:foreach/for/while/list/each/key 及多維遞歸

     編輯:PHP 相關知識

PHP 提供多種陣列遍歷方式,各有語義差異與性能特點。本文系統對比 foreach、for、while+list+each、key、遞歸遍歷,給出選型建議與最佳實踐。

核心遍歷方式對比

方式適用場景鍵值獲取內部指針性能修改原陣列
foreach絕大多數場景$k => $v / $v不影響最快值傳遞(引用可修改)
for數值索引、需索引運算$i => $arr[$i]不影響快直接修改
while+list+each歷史代碼、需手動控制指針list($k,$v)前移慢直接修改
key/next/current極少數底層控制key() / current()手動最慢直接修改

foreach:首選標準

$colors = ['red', 'blue', 'green'];

// 僅值
foreach ($colors as $color) { ... }

// 鍵值
foreach ($colors as $key => $color) { ... }

// 引用修改原陣列
foreach ($data as &$row) {
    $row['processed'] = true;
}
unset($row); // 重要:斷開引用
  • PHP 7+ 複製陣列而非引用,修改不影響原陣列(除非用 &);
  • 遍歷順序 = 插入順序(有序映射特性);
  • 不可在循環中 unset($arr[$key]) 導致跳過元素,改用 array_filter。

for:數值索引專用

$arr = ['zero', 'one', 'two'];
for ($i = 0, $len = count($arr); $i < $len; $i++) {
    echo $arr[$i];
}

// 反向遍歷
for ($i = count($arr) - 1; $i >= 0; $i--) { ... }
  • 需確保連續數值索引(array_values 重建);
  • 適合需索引運算(如兩兩比較、滑動窗口)。

while + list + each:歷史遺留

$colors = ['red', 'blue', 'green'];
reset($colors); // 重置指針
while (list($key, $val) = each($colors)) {
    echo "$key => $val\n";
}
  • each() 返回 [1=>val, 'value'=>val, 0=>key, 'key'=>key];
  • PHP 7.2 棄用,8.0 移除,**新代碼禁用**;
  • 遷移直接改 foreach。

key/next/current:手動指針控制

$capitals = ['Ohio' => 'Columbus', 'Iowa' => 'Des Moines'];
while ($key = key($capitals)) {
    echo $key . "\n";
    next($capitals); // 必須手動前移
}
  • key() 不移動指針,需配合 next();
  • 極少見,除非實現自定義迭代器。

多維陣列遞歸遍歷

function array_recursive_iter(array $arr, callable $callback, int $depth = 0): void {
    foreach ($arr as $key => $val) {
        if (is_array($val)) {
            array_recursive_iter($val, $callback, $depth + 1);
        } else {
            $callback($key, $val, $depth);
        }
    }
}

// 使用:扁平化輸出所有葉子值
$flat = [];
array_recursive_iter($data, function($k, $v) use (&$flat) {
    $flat[] = $v;
});

現代替代:ArrayIterator / RecursiveArrayIterator

$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($data));
foreach ($it as $key => $val) {
    echo str_repeat('  ', $it->getDepth()) . "$key => $val\n";
}

// 過濾葉子節點
$leaves = new RegexIterator($it, '/./', RecursiveRegexIterator::GET_MATCH);
  • SPL 迭代器原生支援遞歸、深度獲取、過濾、限制;
  • 物件風格,可擴展、可組合。

性能微基準(100萬元素)

方法耗時 (ms)記憶體
foreach (值)~45基線
foreach (引用)~50+微增
for~55基線
while+each~120+顯著
RecursiveIteratorIterator~80+物件開銷

最佳實踐清單

  1. 默認用 foreach,語義清晰、性能最優;
  2. 需索引運算用 for;
  3. 遞歸遍歷用 RecursiveIteratorIterator,避免棧溢出、代碼更健壯;
  4. 禁用 each()/list(),PHP 8 已移除;
  5. 引用遍歷後 unset($ref),防止殘留引用污染後續邏輯;
  6. 大數據集考慮 Generator:function gen() { foreach($huge as $v) yield $v; } 分塊處理。

選對遍歷方式,代碼更簡潔、性能更優、維護更易。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved