概要
foreach
は値渡しなので、要素の変更が反映されない- 要素を参照渡しにすると変更ができる
- ただしループ終了直後に
unset
が必要
雛形としては以下のようになる。
1 2 3 4 |
foreach($array as &$value) { $valueの変更処理等 } unset($value); |
警告
foreach
ループを終えた後でも、 $value
は配列の最後の要素を参照したままとなります。 unset() でその参照を解除しておくようにしましょう。 さもないと、次のような目に遭うことになるでしょう。
・・・・・
foreachでは要素の変更ができない
以下のように、foreach
で配列の要素などを変更しようとしても、値渡しのため変更が反映されない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$values = [1, 2, 3]; foreach ($values as $value) { $value *= 2; } print_r($values); // Array // ( // [0] => 1 // [1] => 2 // [2] => 3 // ) |
参照渡しで変更ができる
以下のように要素を参照で渡すと(要素の変数の前にに'&'
を付けると)変更ができるようになる。
1 2 3 4 5 6 7 8 9 10 11 12 |
foreach ($values as &$value) { $value *= 2; } print_r($values); // Array // ( // [0] => 2 // [1] => 4 // [2] => 6 // ) |
注意点
以下のように、その後に再びforeach
で内容を参照すると、最後の要素が繰り返し呼ばれてしまう。
1 2 3 4 5 6 7 8 9 10 11 |
foreach ($values as &$value) { $value *= 2; } foreach ($values as $key => $value) { echo $key, ' => ', $value, "\n"; } // 0 => 2 // 1 => 4 // 2 => 4 |
unsetによる参照のクリア
参照でforeach
を実行した後にunset()
でその参照変数をクリアすることで、その後のループは正常に回る。
1 2 3 4 5 6 7 8 9 10 11 12 |
foreach ($values as &$value) { $value *= 2; } unset($value); foreach ($values as $key => $value) { echo $key, ' => ', $value, "\n"; } // 0 => 2 // 1 => 4 // 2 => 6 |
補足
参照でforeach
を回した後、unset()
せずに通常のforeach
を実行すると、その後にunset()
しても最後の要素が指された状態が残ってしまうようだ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
foreach ($values as &$value) { $value *= 2; } foreach ($values as $key => $value) { echo $key, ' => ', $value, "\n"; } // 0 => 2 // 1 => 4 // 2 => 4 unset($value); foreach ($values as $key => $value) { echo $key, ' => ', $value, "\n"; } // 0 => 2 // 1 => 4 // 2 => 4 |