PHP PHP入門講座 プログラミング

【PHPプログラミング入門講座】ループ処理 (for文)

PHPプログラミングのキービジュアル

番号を指定できるループ処理

記事「【PHPプログラミング入門講座】配列とループ処理 (foreach文)」で説明したforeach文は、配列の要素全てに対して、処理を行うループ処理でした。
しかし、時には次のような処理をしたい場合があります。

  • 配列の開始インデックス 番号や終了のインデックス 番号を指定したい。
  • 配列の要素を1つ飛ばしで処理したい。
  • 配列ではなく通常の数字を使ったループ処理をしたい。
  • もっと複雑なループ処理をしたい。

このような処理は、foreach文ではなく「for文」を使うことで、よりプログラミングしやすくなります。

for文

for文は、「ループ処理開始時の変数の設定」、「ループ処理が継続して実行される条件」、「1回ごとの処理における変数の増加/減少量」の設定ができるループ処理です。
for文の構文は次の通りです。

<構文>

for(開始設定; 継続条件; 更新処理) {
  繰り返す処理
}

それぞれの言葉の意味は次の通りです。

  • 開始設定
    for文を実行する前に変数の初期値を設定します。
    数字や配列のインデックス 番号などの変数に対して初期値を代入する処理を記述します。
  • 継続条件
    ここに書いている条件を満たしている限り、for文のループ処理は実行され続けます。
  • 更新処理
    ループ処理が1回終了する度に変化する変数の処理を記述します。
    数字や配列のインデックス 番号などの増加または減少の処理を記述します。
  • 繰り返す処理
    for文のループ処理により実行される処理を記述します。

以上が構文についての説明です。
では、具体的なfor文を使ったサンプルプログラムを書きます。

サンプルプログラム

例として、110円、90円、80円、100円、60円のリストを表示するfor文を使ったサンプルプログラムを書きます。
次のようになります。

<?php
  $priceList = [110, 90, 80, 100, 60];
  for($i = 0; $i < 5; $i++) {
    echo $priceList[$i] . '円<br>';
  }

このPHPプログラムの読み方が理解できるように、図を使って説明します。

PHPプログラムのfor文の説明図

この図を使ってfor文の説明をします。
図の番号と以下の説明の番号は対応しています。

(1) 変数$priceListに[110, 90, 80, 100, 60]を代入します。
 変数$priceListのデータ型は「配列型」になります。

(2) 開始設定:for文のループ処理の開始設定を記述します。
 通常ここには、配列のインデックス 番号として使用する変数の初期値を代入する処理を記述します。
 このサンプルでは、$iが配列のインデックス 番号として使用する変数です。
 「$i = 0」と書くことで、変数 $i に初期値 0 が代入されます。

(3) 更新処理:forブロックの処理が1回実行された後に、次の処理に向けて値を更新する処理を記述します。
 通常は、インデックス 番号の増加または減少の処理を記述します。
 「 $i++ 」は加算子(インクリメント演算子)であり「変数$iの値を1増加させる」という意味です。
 つまり、ループ処理が1回実行される度に$iの値が1増加します。
 ※加算子(インクリメント演算子)についての詳しい説明は、前の記事「【PHPプログラミング入門講座】代入演算子 / 加算子 / 減算子」をご確認ください。

(4) 継続条件:ここに記述されている条件が満たされている間はforループが実行され続けます。
 「$i < 5」は「変数$iの値が5より小さい場合はforループを繰り返し実行し続ける」という意味です。

ここで、「(2) 開始設定」、「(3) 更新処理」、「(4) 継続条件」の処理をまとめるて説明すると、次のようになります。
(2)開始設定「$i = 0」により、変数$iの初期値として0が代入され、(3)更新処理「$i++」により、forブロックの処理が1回実行される度に変数$iの値が1ずつ増加し、(4)継続条件「$i < 5」を満たす間、forブロック内の処理が繰り返し実行されます。そして、$iの値が5になった時に「$i < 5」の条件を満たさなくなるため、for文の処理が終了します。

(5) forブロックの処理:for文のループ処理により実行される処理を記述します。
 forブロックには「echo $priceList[$i] . '円<br>';」と書かれています。

 これまでの説明からforブロックの処理が1回実行されるたびに「$priceList[$i]」の変数$iが0から4まで1ずつ増加するので、for文の処理を分解すると次のようになります。

<?php
  $priceList = [110, 90, 80, 100, 60];
  echo $priceList[0] . '円<br>';
  echo $priceList[1] . '円<br>';
  echo $priceList[2] . '円<br>';
  echo $priceList[3] . '円<br>';
  echo $priceList[4] . '円<br>';

このようにループ処理で使った変数$iの値を具体的なインデックス 番号に書き換えると、for文の具体的な処理が理解できると思います。

また「$priceList = [110, 90, 80, 100, 60];」から、
$priceList[0] の値が 110
$priceList[1] の値が 90
$priceList[2] の値が 80
$priceList[3] の値が 100
$priceList[4] の値が 60
であることも分かります。

以上より、サンプルプログラムの実行結果は次のようになります。

110円
90円
80円
100円
60円

count関数 (sizeof関数)

先ほどのfor文のサンプルプログラムで、ひとつ気になった点はありませんか?

<?php
  $priceList = [110, 90, 80, 100, 60];
  for($i = 0; $i < 5; $i++) {
    echo $priceList[$i] . '円<br>';
  }

「$i < 5」の部分です。
この5という数字は、配列$priceListの要素数を書いています。
では、もし配列$priceListの要素数を6個に変更した場合は、それに合わせて「$i < 6」に修正しなければならないのでしょうか?

そんなことをしてたら、修正し忘れるようなミスをしやすくなります。
そのような場合は「count関数」または「sizeof関数」を使うと便利です。
「count関数 (sizeof関数)」は配列の要素数を返す関数です。

ちなみに、count関数とsizeof関数はどちらもまったく同じ処理なので、好きな方を使ってOKです。
この記事では、以降ではcount関数を使って説明します。

まず、count関数の動作確認をするために、count関数を使ったサンプルプログラムを書きます。

<?php
  $priceList = [110, 90, 80, 100, 60];
  $count = count($priceList);
  echo '$priceListの要素数は' . $count . 'です。<br>';

  $priceList2 = [110, 90, 80, 100, 60, 80];
  $count2 = count($priceList2);
  echo '$priceList2の要素数は' . $count2 . 'です。<br>';

このPHPプログラムを実行すると次のように出力されます。

$priceListの要素数は5です。
$priceList2の要素数は6です。

配列$priceListの要素数は、[110, 90, 80, 100, 60]の5個なので、count($priceList)は5を返します。
配列$priceList2の要素数は、[110, 90, 80, 100, 60, 80]の6個なので、count($priceList)は6を返します。

では、最初のサンプルプログラムをcount関数を使ったプログラムに修正します。
次のようになります。

<?php
  $priceList = [110, 90, 80, 100, 60];
  for($i = 0; $i < count($priceList); $i++) {
    echo $priceList[$i] . '円<br>';
  }

これで、配列の要素数が変わった場合に、for文の条件を毎回修正するような必要はなくなりました♪

配列のインデックス 番号の最大値を超えた場合

先ほどのサンプルプログラムをもう一度以下に書きます。

<?php
  $priceList = [110, 90, 80, 100, 60];
  for($i = 0; $i < count($priceList); $i++) {
    echo $priceList[$i] . '円<br>';
  }

ここで、継続条件「$i < count($priceList)」の比較演算子が「 < 」にであることに注目してください。
「count($priceList)」は、配列$priceListの要素数であり、5になります。
よって、$iの値は初期設定「$i = 0」で継続条件「$i < 5」を満たすように、0から4まで変化します。
つまり、配列$priceListの最後の要素のインデックス 番号まで処理されます。

では、次のように継続条件の比較演算子「 < 」を「 <= 」に変えるとどうなるでしょうか?

<?php
  $priceList = [110, 90, 80, 100, 60];
  for($i = 0; $i <= count($priceList); $i++) {
    echo $priceList[$i] . '円<br>';
  }

この場合は、for文の$iの値は5まで増加されます。
配列$priceList[5]は存在しない要素ですので、このプログラムを実行すると、次のように値が空の状態で表示されるか、使用しているPHP実行環境の設定によってはエラーが発生します。

110円
90円
80円
100円
60円

配列のインデックス 番号の範囲を正しく指定しているかどうか、意識してプログラムを書くようにしましょう。

for文を使ったサンプルプログラム

for文の特徴をより理解できるように、いくつかサンプルプログラムを書きます。

サンプルプログラム1 (for文の開始設定を変える)

次はfor文の開始設定を「$i = 0」ではなく「$i = 1」に変えたプログラムです。

<?php
  $priceList = [110, 90, 80, 100, 60];
  for($i = 1; $i < count($priceList); $i++) {
    echo $priceList[$i] . '円<br>';
  }

実行結果は次の通りです。

90円
80円
100円
60円

配列$priceListのインデックス 番号$iは1から開始します。
よって、$priceListの1番目の要素($priceList[0])は処理されず、2番目の要素($priceList[1])以降を使ってループ処理が実行されます。

サンプルプログラム2 (for文の継続条件を変える)

次は、配列$priceListの要素数が5であるが、for文の継続条件を配列の要素数よりも少ない「$i < 3」にしたプログラムです。

<?php
  $priceList = [110, 90, 80, 100, 60];
  for($i = 0; $i < 3; $i++) {
    echo $priceList[$i] . '円<br>';
  }

実行結果は次の通りです。

110円
90円
80円

開始設定が「$i = 0」であり、継続条件が「$i < 3」であり、更新処理が「$i++」であるので、ループ処理で設定される$iの値は「0, 1, 2」の3つです。
よって、配列$priceListの要素うちインデックス 番号が 0, 1, 2 である [110, 90, 80] がループ処理に使われます。

サンプルプログラム3 (インデックス 番号を一つ置きに増加させる)

次は、配列のインデックス 番号を 0, 2, 4 というように一つ置きに増加させるプログラムです。

<?php
  $priceList = [110, 90, 80, 100, 60];
  for($i = 0; $i < count($priceList); $i += 2) {
    echo $priceList[$i] . '円<br>';
  }

ところで「$i++」は1つ増加するという意味でした。
しかし、加算子「++」を使って2つ増加させることはできません。

そこで「$i++」は「$i += 1」に書き換えられることを思い出してください。
この書き方なら「$i += 2」と書くこともできるので、これを使って2つずつ$iを増加させることができます。

実行結果は次の通りです。

110円
80円
60円

配列$priceListの要素のうち、インデックス 番号が0番目の110、2番目の80、4番目の60 のみが出力されました。

サンプルプログラム4 (2つの配列をループ)

次は、2つの配列をまとめてループさせるプログラムです。

<?php
  $wdayJapanese = ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'];
  $wdayEnglish = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
  for($i = 0; $i < count($wdayJapanese); $i++) {
    echo $wdayJapanese[$i] . 'は英語で' . $wdayEnglish[$i] . 'です。<br>';
  }

実行結果は次の通りです。

日曜日は英語でSundayです。
月曜日は英語でMondayです。
火曜日は英語でTuesdayです。
水曜日は英語でWednesdayです。
木曜日は英語でThursdayです。
金曜日は英語でFridayです。
土曜日は英語でSaturdayです。

通常の数字を使ったループ処理

for文は配列と共に使う場合が多いですが、通常の数字でも使うこともできます。
例えば、次は掛け算の9の段の答えを表示するPHPプログラムです。

<?php
  for($num = 1; $num <= 9; $num++) {
    $answer = 9 * $num;
    echo $answer . '<br>';
  }

9×1、9×2、9×3、・・・、9×9 までの計算の答えを表示する処理です。
for文の開始設定は1から始まるので「$num = 1」です。
継続条件は「$num <= 9」でも「$num < 10」でもOKです。
このプログラムでは「$num <= 9」を使いました。

実行結果は次の通りです。

9
18
27
36
45
54
63
72
81

数字の値を変化させるループ処理はfor文の記述方法だからできる処理です。foreach文などは配列のループ処理しかできません。

数値が減少するループ処理

これまで更新処理には「$i++」、「$i += 2」、「$num++」など数値が増加するループ処理だけ書きましたが、逆に数字が減少するループ処理も書くことができます。

例えば、次は配列の要素を逆順に表示するサンプルプログラムです。

<?php
  $list = [10, 20, 30, 40, 50];
  for($i = count($list) - 1; $i >= 0; $i--) {
    echo $list[$i] . '<br>';
  }

配列$listの要素を逆順にするということは、配列の最後の要素から最初の要素に向けて値を参照するということです。
そうするには、インデックス 番号を最大値から最初値まで減少させていけば対応できます。

配列の最後の要素のインデックス 番号は、配列の要素数よりも1小さいので「count($list) - 1」です。
配列の最初の要素のインデックス 番号は「 0 」です。

for文の更新処理は、今回は1ずつ減少させるため「$i--」になります。
for文の開始設定は「$i = count($list) - 1」になります。
for文の継続条件は、「配列の最初の要素に到達するまで」です。
よって、「$i--」で1つず減少させていき、$の値が0までループ処理を行うため「$i >= 0」を設定します。

実行結果は次の通りです。

50
40
30
20
10

おわりに

for文は、foreach文よりも複雑なループ処理ができます。
for文は頻繁に使いますので、記事を読み直したり、サンプルプログラムを自分で実際に動作させたりして、身につけていきましょう。

PHPプログラミング入門講座 〜 全記事一覧 〜

-PHP, PHP入門講座, プログラミング
-, , , ,

Copyright© ハッピー・プログラミング・ライフ , 2020 All Rights Reserved.