12

私はphp foreachの反復に疑問を持っています。

以下のコードを見てください。

コード :

   $arr=array(1,2,3);

    echo '$arr value : '. $arr;

    echo '<br>';

    foreach($arr as $arr){
        echo $arr.'<br>';
    }
    echo '$arr value : '. $arr;

出力:

$arr value : Array
1
2
3
$arr value : 3

配列を反復している間、同じ配列名を値キーに使用しましforeach($arr as $arr)たが、正常に動作します。それはどのように機能していますか?

反復中に配列値をオーバーライドしないのはなぜですか?

foreach 反復がどのように機能しているか知りたいです。

私を助けてください!

よろしくお願いしますローガン

4

8 に答える 8

14

反復中に配列値をオーバーライドしないのはなぜですか?

foreachは元の配列のコピーに対して機能するため、foreach ループで変更しても、ループしている値は変更されません。

于 2012-09-07T06:50:29.930 に答える
3

PHP は、メモリ処理に参照カウントcopy on writeを伴うorlazy copyメカニズムを使用します。

foreach 反復の最初の段階で$arrは、「ソフト コピー」されます (実際のコピーではなく、refcountの のzvalのみ$arrayが増加します)。チェックアウトvariable containerlabelPHP 変数の。

私たちの場合には、

  • 最初に実際の$arr変数への参照を保持し、配列の最初の値が参照ポイントからフェッチされます。
  • $arr後で使用するために、最初の配列要素が 2 番目のforeach($arr as $arr )に割り当てられます。
  • 次の反復では、2 番目の配列値が以前に保存された参照ポイントからフェッチされ、その値が同じものに割り当てられて$arr続行されます。
  • の値はループ内で変更されるため、変数$arrを使用してループ外でその配列を出力することはできません。$arr

あなたが理解することを願って...

詳細な調査については、 http://www.php.net/manual/en/internals2.opcodes.fe-fetch.phpおよびhttp://www.php.net/manual/en/internals2.opcodes.feをチェックしてください。 -reset.php

興味深いことに、これでも遊ぶことができます...

current()foreach ループ内では、常に同じ要素が返されます!!!

コード

$source = array(10, 20, 30);
foreach ($source as $value) {
    echo 'Value is ', $value, ', and current() is ', current($source), '<br>';
}

出力

Value is 10, and current() is 20
Value is 20, and current() is 20
Value is 30, and current() is 20
于 2012-09-07T07:30:01.767 に答える
1
foreach ($arr as $arr) {
    // code
}

これがどのように機能するかのあなたのメンタルモデルは次のとおりであるため、これはあなたを混乱させるかもしれません:

  1. PHP は現在の要素を取り出し$arrて配列ポインタを進めます
  2. に値を割り当てます$arr
  3. それは実行します// code
  4. それはステップ1から繰り返されます

それが実際に行うことはこれです(または少なくともそれのおおよその単純化):

  1. PHP はforeach操作を開始し、関連付けられている配列値を取得します。$arr
  2. この配列を内部のどこかに配置します。var iterator
  3. から現在の要素をvar iterator取得し、イテレータを進めます
  4. $arrスクリプトで取得した値を割り当てます
  5. それは実行します// code
  6. 手順 3 から繰り返します

つまり、$arr反復ごとに次の値を取得するのではなく、最初の反復子を取得するためにこれを 1 回だけ使用しました。反復する実際のものは内部に保存され、$arrもう関連付けられていません。つまり$arr、スクリプト内の他の目的には自由に使用でき、PHP は反復ごとに喜んで再利用します。ループが終了すると、最後の要素が に残り$arrます。

匿名関数を知っている場合、これがなぜこのように機能するのかをよりよく示している可能性があります。

foreach($arr, function ($arr) {
    // code
});

foreachこのような関数の実装は、単純に次のようになります。

function foreach(array $array, callable $code) {
    while (list(, $value) = each($array))  {
        $code($value);
    }
}
于 2012-09-07T07:53:29.857 に答える
0

$arr と $arr はコード内で同じです。ソース配列と参照変数は同じ名前です。そのため、foreach は最後に受信した値を保持し、変数を放棄しません。

于 2012-09-07T06:51:08.873 に答える
0

レコードをフェッチするときに配列を上書きしています。コードに $arr からレコードをフェッチし、それを $arr という名前の配列に入れるように要求しているため、$arr = {1 の前に単一のパラメーターで配列全体を上書きしています。 ,2,3}; この行と最初の反復 foreach ($arr as $arr) の後、$arr は配列の最後の要素である 3 に等しくなりました。問題を理解していただければ幸いです。

于 2012-09-07T07:50:49.143 に答える
0

foreach元の配列のコピーを使用して、コードを考えることができます

foreach($arr as $arr){
    echo $arr.'<br>';
}

以下のようなものです:

for ($i = 0, $arr_tmp = $arr, $len = count($arr_tmp); $i < $len; $i++) {
  $arr = $arr_tmp[$i];
  echo $arr.'<br>';
}

$arrこれは、が3最後にある理由を説明しています。

于 2012-09-07T07:00:21.290 に答える
-1

うーん、少し調査した後、次のコードを思いつきました。

<?php
$arr=array(1,2,3);

echo '$arr value : '. $arr;

echo '<br>';

foreach($arr as $arr){
    echo $arr.'<br>';
}

foreach($arr as $key) {
    echo $key.'<br>';
}
echo '$arr value : '. $arr;

この出力は次のとおりです。

$arr value : Array
1
2
3
PHP Warning:  Invalid argument supplied for foreach() in ...file...

これについての私の読みは、ループ内で2番目$arrが最初のものをシャドーイングしているということですが、ループforeachを終了するとすぐforeachに内部でシンボルの設定を解除します($arr

于 2012-09-07T06:52:59.493 に答える
-2

foreach要素を反復処理する前に、最初に左側を評価します。したがって、名前 $arr への再割り当ては $arr を変更しません。

さらに、文書化されているように、ループ変数が外側のコンテキストにリークします。

a と最後の配列要素の参照は$value、foreach ループの後でも残ります。unset() で破棄することをお勧めします。

もちろん、混乱を避けるために、ループする配列とは異なる名前をループ変数に使用する必要があります。

$arr=array(1,2,3);
foreach($arr as $a) { // Note the "as $a", not "as $arr"
    echo $a.'<br>';
}
echo '$arr value : '. $arr;
于 2012-09-07T06:49:35.453 に答える