[PHP]ループ、繰り返し






トップページへ

※動作確認はしておりますが、参考にされる場合は自己責任でお願いします。

 

while, do-whileなど他にもありますが、ここでは for(公式)を使った場合そして foreach(公式)を使った場合のサンプルです。

 

<?php
$file = fopen("test.csv", "r");

$line = fgetcsv($file);

for($i = 0; $i < 25; $i++){
    echo "$line[$i]A<br>";
}
echo '<hr>';
foreach($line as $value){
    echo"$value","B<br>";
}
unset($value);

fclose($file);
?>

test.csvの中身は

歩兵,バズーカ兵,偵察車,軽戦車,重戦車,新型戦車,グレートタンク,輸送車,自走砲,ロケット砲,対空戦車,対空ミサイル,パイプランナー,戦闘機,爆撃機,戦闘ヘリ,輸送ヘリ,ステルス,ブラックボム,戦艦,護衛艦,輸送船,潜水艦,ブラックボート,空母

です。

 

実行すると

歩兵A
バズーカ兵A
偵察車A
・・・
ブラックボートA
空母A


歩兵B
バズーカ兵B
偵察車B
・・・
ブラックボートB
空母B

です。つまり、このサンプルでは for でも foreach でも同じ結果です。

 

ちなみに

forはデータの個数がわかっている場合に使えます。

一方

foreachはデータの個数が不明の場合でも使えますが、配列のみに使えます。


備考

・ループを終了(途中で停止)させる場合は break を使用します。

・詳しくは公式

<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
}
// $arr は array(2, 4, 6, 8) となります
unset($value); // 最後の要素への参照を解除します
?>

・foreachの公式警告サンプルを実行すると(echo ‘$value : ‘;と補足しているのでサンプルと見た目が異なります)

$value : 2
$value : 4
$value : 6
$value : 8

&$valueのように&を付加すると、要素の変更が可能。

1番目のforeach後の $arr の中身は

array(1, 2, 3, 4) つまり $arr[0]は1, $arr[1]は2, $arr[2]は3, $arr[3]は4。

 

↓ 実行後

array(2, 4, 6, 8) つまり $arr[0]は2, $arr[1]は4, $arr[2]は6, $arr[3]は8。

パターンA 「unsetをしない」と、$valueは「最後の要素である $arr[3]」を指したままである。

array(2, 4, 6, 8)のとき、foreach ($arr as $key => $value) を実行すると、

$arr[0]→$valueの中身は2
$arr[1]→$valueの中身は4
$arr[2]→$valueの中身は6
$arr[3]→本来、$valueの中身は8 となるはず

しかし$valueが $arr[3]を指しているために、$arr[3]の時は array(2, 4, 6, 8)の方を参照せずに、自分自身を参照してしまう。その結果、$valueに最後に入った値 6 を参照しセットしてしまう。

0 => 2Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 2 )
1 => 4Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 4 )
2 => 6Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 6 )
3 => 6Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 6 )

 

パターンB 「unsetをする」と、$valueはリセットされ「最初の $arr[0]」を指す。

array(2, 4, 6, 8)のとき、foreach ($arr as $key => $value) を実行すると、

$arr[0]→$valueの中身は2
$arr[1]→$valueの中身は4
$arr[2]→$valueの中身は6
$arr[3]→$valueの中身は8

0 => 2Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 )
1 => 4Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 )
2 => 6Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 )
3 => 8Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 )

結論 こんなミスをしないためには?

・&をつけることによる要素変更を行うのなら、unset($value);を確実に実施する。

・&による要素変更は使用しない。

・公式のサンプルでいえば、2番目の foreach では $valueではなく、例 $value2 と別の変数を使う。

foreach ($arr as $key => $value2) {
echo "{$key} => {$value2}";
print_r($arr);
}

※余談ですが、公式の警告サンプルで $arr = array(1, 2, 10, 4);と実行すると

$value : 2
$value : 4
$value : 20
$value : 8
0 => 2Array ( [0] => 2 [1] => 4 [2] => 20 [3] => 2 )
1 => 4Array ( [0] => 2 [1] => 4 [2] => 20 [3] => 4 )
2 => 20Array ( [0] => 2 [1] => 4 [2] => 20 [3] => 20 )
3 => 20Array ( [0] => 2 [1] => 4 [2] => 20 [3] => 20 )

となりますし、$arr = array(1, 2, 3, 4, 5);と実行すると

$value : 2
$value : 4
$value : 6
$value : 8
$value : 10
0 => 2Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 2 )
1 => 4Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 4 )
2 => 6Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 6 )
3 => 8Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 8 )
4 => 8Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 8 )

となりました。同様に $arr[4]の時は自分自身を参照してしまうので、直前に入った 8 がセットされてしまいます。

 

公式サイトへ

fopen

fgetcsv

fclose

 

参考にさせて頂いたサイト様

https://techacademy.jp/magazine/12298

 

PHP(楽天市場で探すamazonで探す)メニューへ戻る

 






関連記事
[PHP]日付関連

[PHP]配列

[PHP]JavaScriptとの連携

[PHP]雑記帳

[PHP]エラー例