基本語法
// 僅取值
foreach ($array as $value) {
// ...
}
// 取鍵值對
foreach ($array as $key => $value) {
// ...
}
陣列遍歷範例
一維索引陣列
$array1 = [1, 2, 3, 4, 5];
foreach ($array1 as $abc) {
echo "new value is " . ($abc * 10) . "<br>";
}
// 輸出 10, 20, 30, 40, 50
關聯陣列
$a = ["one" => 1, "two" => 2, "three" => 3, "seventeen" => 17];
foreach ($a as $k => $v) {
echo "\$a[$k] => $v.\n";
}
多維陣列
$a = [
["a", "b"],
["y", "z"]
];
foreach ($a as $v1) {
foreach ($v1 as $v2) {
echo "$v2\n"; // a, b, y, z
}
}
動態陣列直接遍歷
foreach ([1, 2, 3, 4, 5] as $v) {
echo "$v\n";
}
核心運作機制
- foreach **複製陣列指標** 進行迭代,不會移動原陣列內部指標 (PHP 7+)。
- 每次迴圈取得的是**值的副本**,修改
$value **不會影響原陣列**。
- 需修改原陣列請用
$array[$key] = ... 或傳址 foreach ($array as $key => &$value) (PHP 5.3+)。
修改原陣列範例
$arr = ['a', 'b', 'c'];
foreach ($arr as $key => &$val) {
$val .= '_modified';
}
unset($val); // 解除參考,避免後續誤用
print_r($arr); // ['a_modified', 'b_modified', 'c_modified']
foreach vs while / for 效能
- **foreach 最快**:專為陣列優化,語意清晰。
for 適用已知長度索引陣列,需手動管理索引。
while(list($k,$v)=each($arr)) 已棄用 (PHP 7.2+)。
常見陷阱
| 陷阱 | 解決 |
迴圈中 unset($array[$key]) 導致索引錯亂 | 改用 array_filter 或反向迴圈 |
參考殘留 &$val 影響後續邏輯 | 迴圈結束呼叫 unset($val) |
| 遍歷大陣列記憶體暴增 | 考慮 Generator (yield) 分批處理 |
最佳實踐建議
- 優先使用
foreach ($arr as $k => $v) 可讀性最高。
- 需修改原值加
& 並記得 unset。
- 多維陣列善用巢狀 foreach 或
array_walk_recursive。
- 大量資料搭配
yield 產生器避免一次載入記憶體。