<?php
$arr = ['one', 'two', 'three'];
// 僅取值
foreach ($arr as $value) {
echo "Value: $value
";
}
// 取鍵與值
foreach ($arr as $key => $value) {
echo "Key: $key, Value: $value
";
}
$arr = ['a', 'b', 'c'];
// ✅ 正確:參考傳遞修改值
foreach ($arr as &$value) {
$value = strtoupper($value);
}
unset($value); // ★★★ 關鍵:解除參考綁定
print_r($arr); // ['A', 'B', 'C']
// ❌ 錯誤:忘記 unset 導致後續迴圈異常
foreach ($arr as &$value) { $value = strtoupper($value); }
// 此時 $value 仍參考 $arr[2]
foreach ($arr as $value) { // 以值模式迴圈
// $value 複製值給 $arr[2]!導致最後一元素被覆蓋
echo $value; // 輸出:A B B(最後變成倒數第二個值)
}
unset($value); // 補救
PHP 陣列迴圈時會複製陣列(Copy-on-Write),但參考傳遞 `&$value` 會強制建立對原陣列元素的參考。迴圈結束後,`$value` 仍參考最後一個元素。若後續以值模式 `foreach ($arr as $value)` 迴圈,PHP 會將 `$value` 的值複製給每個元素,**包括最後一個**,導致最後一元素被倒數第二個值覆蓋。
foreach ($arr as &$v) {
$v = process($v);
}
unset($v); // 必須
foreach ($arr as $v) { /* 唯讀 */ }
foreach ($arr as $k => $v) {
$arr[$k] = process($v);
}
foreach ($arr as $v) { /* 唯讀 */ }
// 返回新陣列,不修改原陣列
$new_arr = array_map('process', $arr);
// 修改原陣列(內部用參考)
array_walk($arr, function(&$v) { $v = process($v); });
$arr = ['a', 'b', 'c', 'd'];
foreach ($arr as $key => $value) {
if ($value === 'b') {
unset($arr[$key]); // 安全:不影響迴圈指標
}
}
// 結果:['a', 'c', 'd'](鍵名保留 0,2,3)
$arr = ['a', 'b'];
foreach ($arr as $key => $value) {
if ($value === 'a') {
$arr[] = 'new'; // 不會在本次迴圈被處理
}
}
// 迴圈只跑 2 次
$users = [
['name' => 'Alice', 'tags' => ['php', 'js']],
['name' => 'Bob', 'tags' => ['python']],
];
foreach ($users as $user) {
echo $user['name'] . ': ';
foreach ($user['tags'] as $tag) {
echo $tag . ' ';
}
echo "
";
}
$people = [
['Alice', 25, 'Engineer'],
['Bob', 30, 'Designer'],
];
foreach ($people as [$name, $age, $job]) {
echo "$name ($age) - $job
";
}
// 關聯陣列解構
foreach ($people as ['name' => $name, 'age' => $age]) {
echo "$name is $age years old
";
}