PHP 提供 for、foreach、while、do-while 多種循環結構。本文聚焦 for 與 foreach 的核心差異,從語法特性、底層實現、性能基準、適用場景四個維度深度對比,助你做出最佳選擇。
for (expr1; expr2; expr3) statement
// expr1: 初始化(僅執行一次)
// expr2: 條件判斷(每次迴圈前執行,true 繼續)
// expr3: 迭代步進(每次迴圈後執行)
所有表達式均可為空,expr2 為空視為無限循環(需 break 跳出)。
// 格式一:僅取值
foreach ($array as $value) { /* ... */ }
// 格式二:同時取鍵與值
foreach ($array as $key => $value) { /* ... */ }
關鍵特性:
Traversable 介面的物件,否則報錯reset())@ 抑制錯誤| 維度 | for | foreach |
|---|---|---|
| 迭代器 | 手動管理索引/指標 | 內部迭代器自動推進 |
| 陣列存取 | 隨機存取 $arr[$i] | 順序存取,鍵值直接綁定 |
| 副本機制 | 無(直接操作原陣列) | PHP 5:完整複製;PHP 7+:Copy-on-Write |
| 鍵類型支援 | 僅整數索引(需自行處理關聯陣列) | 原生支援字串鍵、整數鍵混合 |
$arr = range(1, 1_000_000);
// for 循環
$start = hrtime(true);
for ($i = 0, $len = count($arr); $i < $len; $i++) { $sum += $arr[$i]; }
echo "for: " . (hrtime(true) - $start) / 1e6 . " ms\n";
// foreach 循環
$start = hrtime(true);
foreach ($arr as $v) { $sum += $v; }
echo "foreach: " . (hrtime(true) - $start) / 1e6 . " ms\n";
典型結果:
for:~12-15 msforeach:~8-10 ms結論:
foreach通常快 20%-40%,得益於內部迭代器優化、無邊界檢查、鍵值直接綁定。但對於簡單數值索引陣列,差距在微秒級,實際專案中可讀性優先。
Iterator/IteratorAggregatefor ($i=count-1; $i>=0; $i--))// 方法一:引用修改(記得 unset)
foreach ($arr as &$v) { $v *= 2; }
unset($v);
// 方法二:鍵名索引修改(推薦)
foreach ($arr as $k => $v) { $arr[$k] = $v * 2; }
$arr = [1,2,3,4,5];
for ($i = 0; $i < count($arr); $i++) {
if ($arr[$i] === 3) {
array_splice($arr, $i, 1); // 刪除當前元素
$i--; // 索引回退
}
}
$matrix = [[1,2], [3,4], [5,6]];
// foreach 巢狀(推薦)
foreach ($matrix as $row) {
foreach ($row as $val) { echo $val; }
}
// for 巢狀(需知維度)
for ($i = 0; $i < count($matrix); $i++) {
for ($j = 0; $j < count($matrix[$i]); $j++) {
echo $matrix[$i][$j];
}
}
視圖模板中常用:
foreach ($items as $item):
echo $item;
endforeach;
for ($i=0; $i<10; $i++):
echo $i;
endfor;
unset() 忘記風險。yield 逐行產生,記憶體常數級,配合 foreach 使用。選對循環結構,不僅是性能優化,更是代碼意圖的清晰表達。大多數情況下,foreach 是表達「遍歷集合」最自然的語言工具。