名前の重複

<?php
$user = "hoge";
$users = array(
        1 => array('name' => "taro"),
        2 => array('name' => "jiro"),
        3 => array('name' => "saburo"),
	);

foreach($users as $key => $arr) {
    foreach($arr as $user) {

    }
}

echo $user;

 こういうコードがあったとすると、最後のechoは何を出力するだろうか?
$userには"hoge"が代入されているのだから、hogeだろうか?

 
一体どうしたことだろう。出力されるのはsaburoである。saburoは、まったく別の変数のしかも最後の値にすぎない。


 なぜなのだろうか。よく見てみると、foreachのループ変数と外の変数との間で、$userという名前が重複している。


 だがそれでどうしてsaburoになるのか?


 as $userによって、$arrの要素はループの中で$userという変数名で扱うことができるが、$userはスコープの外の$userと名前が衝突したために同じものをさす。
foreachのループと共に、$userにはtaro、jiro、saburoが刻々と代入されていく。
ループを抜けるときsaburoを指していた$userは、スコープの外の変数名と一致しているために破棄されない。

 外のスコープの$userは、一見そうは見えないにもかかわらず、ループ変数の最後の値を指している状態となるため、出力されるのはsaburoとなる。


 代入演算子が見えていれば一瞬で気がつくだろうが、foreachのasも代入と同じように外の変数に影響するということは忘れがちで
しかも一見かなり想像とは異なる出力結果になる。