次のようなコードがあります:
$a = array ('zero','one','two', 'three');
foreach ($a as &$v) {
}
foreach ($a as $v) {
echo $v.PHP_EOL;
}
出力が「ゼロ、1、2、2」となる理由を誰か説明してもらえますか。
Zend 認定試験学習ガイドより。
ベストアンサー1
a[3]が各反復で変化する理由を理解するのに数時間を費やさなければなりませんでした。これが私が到達した説明です。
PHP には、通常の変数と参照変数の 2 種類の変数があります。変数の参照を別の変数に割り当てると、その変数は参照変数になります。
例えば
$a = array('zero', 'one', 'two', 'three');
もしそうするなら
$v = &$a[0]
0 番目の要素 ( $a[0]
) は参照変数$v
になります。 はその変数を指しているので、 に変更を加えると にも$v
反映され$a[0]
、その逆も同様です。
今、もし私たちが
$v = &$a[1]
$a[1]
参照変数になり、$a[0]
通常の変数になります (誰も$a[0]
それを指していないので、通常の変数に変換されます。PHP は、誰もそれを指していない場合は通常の変数にするほど賢いです)
最初のループではこうなります
foreach ($a as &$v) {
}
最後の反復の後は$a[3]
参照変数になります。
はへの変更$v
を指しているので、への変更はへの変更につながります。$a[3]
$v
$a[3]
2番目のループでは、
foreach ($a as $v) {
echo $v.'-'.$a[3].PHP_EOL;
}
各反復で が$v
変化すると、$a[3]
も変化します。( は$v
まだ を指しているため)。これが、各反復で が変化する$a[3]
理由です。$a[3]
最後の反復の前の反復では、 に$v
値「2」が割り当てられます。$v
は を指しているため$a[3]
、$a[3]
は値「2」を取得します。このことに留意してください。
最後の反復では、$v
( を指す) は、前の反復で 2 に設定されていた$a[3]
ため、現在は 'two' の値を持ちます。が印刷されます。これが、最後の反復で $v が印刷されるときに 'two' が繰り返される理由です。$a[3]
two