PHP foreachはループを渡した後のことを引用

2413 ワード

foreachはPHP文法で最もよく使われる.foreachは直接循環構造を便利にすることができて、引用の方式で遍歴することができて、遍歴の過程で元の循環構造を修正して今日foreachが引用の方式で、循環の後のいくつかの事について話します.
  • case 1
  • $a = [0,1,3,5];
    foreach ($a as $key => &$item) {
    	echo $item.' ';
    }
    print_r($a);
    $item = 10;
    print_r($a);
    
    

    上のコード出力を見てみましょう:echo: 0 1 3 52つのprint_rの出力内容
    (
        [0] => 0
        [1] => 1
        [2] => 3
        [3] => 5
    )
    Array
    (
        [0] => 0
        [1] => 1
        [2] => 3
        [3] => 10
    )
    

    上からforeachリファレンスループの後、$itemは解放されず、配列の最後の要素へのリファレンスであるため、後続のコードで同じ名前のループが使用されると、元の配列に同時に影響します.
  • case 2
  • $a = [0,1,3,5];
    foreach ($a as $key => &$item) {
    	echo $item.' ';
    	if($key>1){
    		break;
    	}
    }
    print_r($a);
    $item = 10;
    print_r($a);
    
    

    上のコード出力を見てみましょう:echo: 0 1 3 52つのprint_rの出力内容
    (
        [0] => 0
        [1] => 1
        [2] => 3
        [3] => 5
    )
    Array
    (
        [0] => 0
        [1] => 1
        [2] => 10
        [3] => 5
    )
    

    以上の出力結果から,$itemは常にループジャンプ前の最後の要素を指すことがわかる.
  • case 3
  • $a = [0,1,3,5];
    foreach ($a as $key => &$item) {
    	echo $item.' ';
    }
    print_r($a);
    foreach($a as $key => $item)
    {
    	echo $item;
    }
    print_r($a);
    
    

    上のコード出力を見てみましょう:echo1: 0 1 3 5,echo2:0 1 3 32つのprint_rの出力内容
    (
        [0] => 0
        [1] => 1
        [2] => 3
        [3] => 5
    )
    Array
    (
        [0] => 0
        [1] => 1
        [2] => 3
        [3] => 3
    )
    

    この結果は少しまちまちで、ネット上ではPHP foreachのバグだと言う人がたくさんいますが、よく分析すると、実はバグではありません.2つ目のサイクルを分解します
  • $t = $a[0]; $item = $t;//このとき$a[3]=$a[0],$aの内容[0,1,3,0]
  • $t = $a[1]; $item = $t;//このとき$a[3]=$a[1],$aの内容[0,1,3,1]
  • $t = $a[2]; $item = $t;//このとき$a[3]=$a[2],$aの内容[0,1,3,3]
  • $t = $a[3]; $item = $t;//このとき$a[3]=$a[3],$aの内容[0,1,3,3]
  • 上記の3つの状況から、foreachリファレンスが伝達された後、unset($item)が必要であり、リファレンスに接触する必要があります.そうしないと、ループ後のコードにループ内の変数名があると、バグが発生しやすくなります.大規模なシステムは一人で完成するわけではないので、複数の人が協力するときは、必ず自分のデータをきれいに処理し、バグを避けなければなりません.
    その他の参照関連
    
    $arr = [0,1];
    $arr = [&arr];
    var_dump($arr === $arr[0]);
    
    

    以上の出力結果はtrueです.$arrと$arr[0]は同じデータアドレスを指すためです.
    $arr = [0,1];
    function test($item,$key,&$arr){
        unset($arr[$key]);
    }
    array_walk($arr, 'test',$arr);
    var_dump($arr);
    
    

    以上の出力内容は[0,1]です.