foreach 是 PHP 遍歷數組/可遍歷對象的專用語法,比 for/while+each 更簡潔、安全。本文系統講解雙語法、鍵值語義、嵌套遍歷、引用陷阱、性能特徵。
// 1. 僅獲取值
foreach ($array as $value) {
// $value 為當前元素值
}
// 2. 同時獲取鍵和值 (推薦)
foreach ($array as $key => $value) {
// $key 為當前元素鍵 (整數索引或字符串鍵名)
// $value 為當前元素值
}
$value **不影響**原數組。current()/next()/reset() 等內部指針函數。TypeError (PHP 8+) 或警告。$arr = [1, 2, 3];
foreach ($arr as &$value) { // 加 & 符號
$value *= 2;
}
unset($value); // **關鍵**:解除引用,防止後續代碼誤修改最後一個元素
print_r($arr); // [2, 4, 6]
最佳實踐:需要修改原數組時使用引用,循環結束**立即 unset($value)**。
function printTree(array $arr, int $depth = 0) {
foreach ($arr as $key => $value) {
echo str_repeat(' ', $depth) . "$key => ";
if (is_array($value)) {
echo "\n";
printTree($value, $depth + 1);
} else {
echo "$value\n";
}
}
}
$data = [
'user' => ['name' => 'Zhang', 'age' => 25],
'roles' => ['admin', 'editor'],
'active' => true
];
printTree($data);
| 陷阱 | 現象 | 解決 |
|---|---|---|
| 引用殘留 | 循環後 $value 仍引用最後元素,後續賦值污染數組 | unset($value) |
| 循環中刪除元素 | unset($arr[$key]) 可能導致跳過下一元素 | 先收集待刪鍵,循環後批量刪除;或反向遍歷 |
| 修改鍵名 | 不支援直接修改 $key 影響原數組 | 重建新數組 $new[$newKey] = $value |
| 遍歷對象屬性 | 默認只遍歷可見屬性 | 實現 IteratorAggregate 或 Traversable |
foreach:內部優化優於 for+count() 或 while+each()。$len = count($arr)、$keys = array_keys($arr)。$key =>:微小但可測量的開銷差異。yield:惰性產生元素,極大節省記憶體 (如讀取大文件/數據庫結果集)。for 循環// 索引數組且需索引運算時 for 更靈活
for ($i = 0, $len = count($arr); $i < $len; $i++) {
// 可隨意跳過、回退、修改索引
}
// 關聯數組/對象 foreach 唯一選擇
掌握 foreach 細節,寫出更安全、高效、符合 PHP 風格的遍歷代碼。