Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

  1. トップページ
  2. PHP入門編 - 繰り返し処理を行うfor文について

繰り返し処理を行うfor文について

みなさまどうも。

今回は『for文』について色々とやっていきましょう。ちょっと前に紹介した配列がいっぱいでてきます。なのでちょっと自信なかったら配列の記事なんかを再度読んでみると調子よいかもしれません。

ではいきましょう。『for文』とは一定回数繰り返しする処理を構築できる構文です。例えば『echo』を1万回実行させたりといった暴挙も簡単に行うことができます。(PCに結構負担がかかりますので遊びで実行するときは千回くらいにしておきましょう)

んでもって、いきなりですがちょっと注意点です。この『for文』は初心者の事故が非常に多い構文です。というのも『for文』の記述を間違えると永遠と処理を続けてしまう処理が簡単に出来上がるからです。プログラミングの世界ではこれを『ループ』といいます。

PHPをローカル(MAMPとか)で実行させているのであれば、延々と終わらないループ処理を実行させてもみなさんのPCに負担がかかるだけで済みます。しかしそういった処理をレンタルサーバーに上げて実行してサーバーを落としてしまったりすると、そのレンタルサーバーを間借りしている他のウェブサイトの管理人さんに大迷惑がかかります。気をつけるようにしてくださいね。

(´-`).。oO(まあ、最近のマシンだとPHPでのループ処理くらいで落ちることは滅多にありませんが...)

(´-`).。oO(古いマシンでずっとレンタルサーバーを運営している会社さんがたまにいるので要注意です...)

では改めまして『for文』の記述方法から確認していきましょう。基本的な構文はこのようになります。

<?php
for($num = 0; $num < 10; ++$num){
    echo $num;
}

これで『echo $num;』が10回実行されます。(0から数え始めているので0~9で10回になります)出力結果は以下になりますね。

0123456789

なんだかちょっと複雑な感じですよね。ちょいと細かく見て行きましょう。

まずは『for』と記述してその後に『()』と記述します。この『()』の中がループをする条件、となっています。ここが慣れないとちょっと難しいです。

『()』の中の『;』ごとに分けて考えていきます。『$num = 0』と『$num < 10』と『++$num』に分かれていますね。最後の『;』は記述しませんので記述する『;』は2つだけです。

最初の『$num = 0』という部分ですが、これは『初期化』と呼ばれる部分になります。『初期化』は変数の解説の記事でもでてきましたね。要するに『変数に最初に代入する始まりとしての数値』のようなものです。上記の場合は『$num = 0』となっていますので「変数『num』の最初の数値は『0』だよー」と宣言しているような感じです。この初期化処理は『for文』が実行される前の最初の1回しか処理が走りません。これがとっても重要なので覚えておいてください。すぐ後にでてきます。

続いて『$num < 10』という部分です。これは「変数『num』が『10』以下の場合はループ処理を続けてね」と指示している部分になります。逆に考えると「変数『num』が『10』を上回った場合は処理を抜けてね」という指示になります。一般にここの部分は『条件』とか『条件式』とか呼ばれたりしますね。正式名はないっぽいです。ここの処理は『for文』が繰り返される度に処理が走ります。

さて最後の『++num』です。これはループ処理を1回行う度に演算される部分です。『++』と記述してありますね、つまり「1回処理を行う度に変数『num』の値に『1』を加算してね」という指示になります。もし『2』を加算したければ『$num + 2』って記述してあげればOKです。ここは一般に『更新』もしくは『更新式』、『更新部分』とか言われます。こちらも正式名は多分ないみたいです。(あったらごめんなさい)こちらも『for文』が繰り返される度に処理が走るところになりますね。

さてじゃあ丸ごと日本語で再確認してみましょう。「最初に変数『num』に『0』を代入してループ処理1回ごとに変数『num』に『1』を加算して変数『num』が『10』以上になったらループ処理を抜けてね」といった感じです。

ループ処理で実行させる処理の内容は『{}』の中に記述します。今回は『echo $num;』と書いてありますね。ここも注目すべきところです。条件が記述してある『()』の中で使用した変数『num』がそのまま使われています。条件が記述してある『()』の中で使用した変数をそのまま使用する、という使い方も『for文』を使用するにあたって大切なところになりますね。

では上記のことを踏まえつつちょっと処理を書いてみましょう。ちょっと前の記事で書いたボーカロイドさんのお名前を出してくれるやつありましたよね。あれを全てのメンバーのお名前出力してくれるようにアップデートしてみましょう。この処理は『for文』と配列の数を教えてくれる『count()』との合わせ技で構築できます。

というわけで書いてみます。まず配列の定義からですね。

<?php
$vocaloids = [];
$vocaloids[] = '初音ミク';
$vocaloids[] = 'IA';
$vocaloids[] = '鏡音リン';

そしたら配列『vocaloids』の数だけ『for文』を回したいので以下のような感じになります。まだ『for文』の中は空でございます。

<?php
$vocaloids = [];
$vocaloids[] = '初音ミク';
$vocaloids[] = 'IA';
$vocaloids[] = '鏡音リン';

for($i = 0; $i <= count($vocaloids) - 1; ++$i){

}

『for文』のループで使用する変数名は『i』とか『j』とか『k』にされることが多いです。

由来はよくわからないのですが、著者が小学生くらいの頃に読んだプログラミング系の参考書(C言語)でもなぜか全部『i』になっていました。数学で階差数列とかの添字に『i』とか『k』とか使うのでそれが由来だと思ってましたが、調べてみるとはっきり言えない感じのようです。

これはちょっとした昔からの慣習になりますね。著者もなんだか『for文』の時の変数名は『i』とか『j』とか『k』じゃないと落ち着かない感じがします。

こうすることで配列の数だけループ処理を行うことができます。そしたら『for文』の『{}』の中に配列の各要素の値を出力する処理を記述すればOKです。

<?php
$vocaloids = [];
$vocaloids[] = '初音ミク';
$vocaloids[] = 'IA';
$vocaloids[] = '鏡音リン';

for($i = 0; $i <= count($vocaloids) - 1; ++$i){
    echo $vocaloids[$i] . "\n"; // 配列『vocaloids』の各要素のインデックス番号は変数『i』の変化する各値と同じなので『$vocaloids[$i] 』で配列『vocaloids』の全ての要素の値を出力することができます。
}

これを実行させると以下のテキストが返って来ます。

初音ミク
IA
鏡音リン

ちゃんと出力できていますね。『$vocaloids[$i]』というところがミソです。変数『i』の値は『for文』が実行される度に値が変わり、その値は配列『vocaloids』の各要素のインデックス番号と一致しています。なのでその変数『i』の値を配列『vocaloids』のインデックス番号として使用すれば、配列『vocaloids』の全ての要素の値を出力できる、といった感じですね。

なので注意すべき点としては上記の場合ですと、『$i <= count($vocaloids) - 1』のところになります。配列の解説の記事でもありましたが、配列は『0』から数え始めますので『count()』で取得できる数とは『1』ずれていますね。

上記の場合で具体的に言うと『count()』で取得できる配列数は『3』ですが『1, 2, 3』で3回実行させるのではなく、『0, 1, 2』で3回実行させるので最大数は『2』になります。なので『$i <= count($vocaloids) - 1』といった感じで『1』が減算されている、といった感じです。

「面倒くさいから『count()』で取得できる値に合わせて『$i = 1; $i <= count($vocaloids); ++$i』とすれば楽なんじゃないか」と思う方もいらっしゃるかもしれませんが、配列は『0』から数え始めるため、初期値を『$i = 1』としてしまうと配列『vocaloids』の各要素のインデックス番号と変数『i』の値が一致しなくなってしまい、配列を処理する部分を『$vocaloids[$i - 1]』と記述しなくてはならなくなるため、逆に面倒くさくなってしまいます。

ここまでは大丈夫そうでしょうか。

さて、先ほどのサンプルはちゃんとボーカロイドのみなさんのお名前が出力できているのでこれでOKな気がしてしまいますが実はちょっと修正するべき点があります。それは『for文』の『()』の中の『$i <= count($vocaloids)』という部分です。

先ほど、『for文』の『初期化』の部分(上記で言うと『$i = 0』の部分)は一度しか実行しませんが、『条件式』の部分(上記で言うと『$i <= count($vocaloids) - 1』の部分)は『for文』が繰り返される度に処理が走ってしまう、といった解説をしました。ということは『条件式』の部分に『$i <= count($vocaloids) - 1』と記述すると、『count()』と減算の処理が毎回実行されてしまうということになります。

『$i <= count($vocaloids)』で取れる値は一定で、変化がありませんので毎回『count()』の処理を走らせて減算する必要はありませんよね。なので『count()』で取得した値を一旦変数などで保存し、それを『for文』の中の『条件式』で使用することで処理を軽減することができます。

<?php
$vocaloids = [];
$vocaloids[] = '初音ミク';
$vocaloids[] = 'IA';
$vocaloids[] = '鏡音リン';

$cnt = count($vocaloids) - 1; // 『count()』で取得した値を減算して変数『cnt』で受け取ります。
for($i = 0; $i <= $cnt; ++$i){ // 更新式を『$i <= $cnt』とすることで処理を軽減できます。
    echo $vocaloids[$i] . "\n";
}

このような感じで『count()』に限らず、『更新式』と『条件式』の部分はなるべくPHPに処理をさせない方向で構築するようにすると良いでしょう。何千回、何万回と『for文』を実行させる場合は『更新式』と『条件式』を上手く実装するだけで処理速度が5倍以上変化することもあります。意外と侮れませんので要注意ですね。

というわけで以上となります。『for文』はちょっと慣れないと構文が難しいかもしれませんが大丈夫そうでしょうか。続いての記事では同じく繰り返し処理をさせる『while文』についてもろもろやっていきたいと思います。ではではこの辺で。またお会いしましょう。

この記事は桜舞が執筆致しました。

著者が愛する小型哺乳類

桜舞 春人 Sakurama Haruto

ISDN時代から様々なコンテンツを制作しているちょっと髪の毛が心配な東京在住のプログラマー。生粋のロングスリーパーで、10時間以上睡眠を取らないと基本的に体調が悪い。好きなだけ寝れる生活を送るのが夢。ゲームとスポーツと音楽が大好き。誰か髪の毛を分けて下さい。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。