この配列を2回繰り返すと、PHPが値を上書きするのはなぜですか(参照により、値によって)
質問
アレイを2回繰り返して参照してから値で1回、PHPは各ループに同じ変数名を使用すると、配列の最後の値を上書きします。これは、例を介して最もよく示されています。
$array = range(1,5);
foreach($array as &$element)
{
$element *= 2;
}
print_r($array);
foreach($array as $element) { }
print_r($array);
出力:
array([0] => 2] => 4 [2] => 6 [3] => 8 [4] => 10 )
array([0] => 2] => 4 [2] => 6 [3] => 8 [4] => 8 )
私は修正を探していないことに注意してください。なぜこれが起こっているのかを理解したいと考えています。また、各ループの変数名がそれぞれ呼び出されていない場合には発生しないことに注意してください $element
, 、だから私はそれが関係していると推測しています $element
最初のループの終了後もスコープと参照にあります。
解決
最初のループ$要素の後、$ arrayの最後の要素/値への参照です。
print_r()の代わりにvar_dump()を使用するときにそれを見ることができます
array(5) {
[0]=>
int(2)
...
[4]=>
&int(2)
}
&inに注意してください &int(2)
.
2番目のループを使用すると、値を$要素に割り当てます。そして、それはまだ参照であるため、配列の値も変更されます。一緒に試してみてください
foreach($array as $element)
{
var_dump($array);
}
2番目のループと表示されます。
それは多かれ少なかれ同じです
$array = range(1,5);
$element = &$array[4];
$element = $array[3];
// and $element = $array[4];
echo $array[4];
(ループと乗算だけで...ねえ、私は「多かれ少なかれ」と言いました;-))
他のヒント
これがそうです 男自身からの説明:
$y = "some test"; foreach ($myarray as $y) { print "$y\n"; }
ここ
$y
「テスト」を含む文字列を参照するシンボルテーブルエントリです。最初の反復では、本質的に行います。$y = $myarray[0]; // Not necessarily 0, just the 1st element
したがって、関連するストレージ
$y
からの値によって上書きされます$myarray
. 。もしも$y
参照を介して他のストレージに関連付けられていることは、そのストレージが変更されることになります。今、あなたがこれを行うとしましょう:
$myarray = array("Test"); $a = "A string"; $y = &$a; foreach ($myarray as $y) { print "$y\n"; }
ここ
$y
と同じストレージに関連付けられています$a
参照を通じて、最初の反復が行われたとき:$y = $myarray[0];
「テスト」文字列が行くことができる唯一の場所は、に関連するストレージにあります
$y
.
これがあなたがこの問題を修正する方法です:
foreach($array as &$element)
{
$element *= 2;
}
unset($element); #gets rid of the reference and cleans the var for re-use.
foreach($array as $element) { }