代入演算子の延長でインクリメント演算子とデクリメント演算子を見ておきましょう。
上の代入演算子と同様に、変数に1を足したり引いたりする処理も頻繁に行われます。これは、以下のような記述です。
$num = $num + 1;
例えば、回数など数えるカウンターとして整数の変数を用いる場合などに使われます。1を加算することをインクリメント、1を減算することをデクリメントといいます。
これを行う演算子が「++」と「--」です。変数の前か後ろに置き、以下のように記述できます。
$num++;
上の例では変数の後ろに置きましたが、「++$num」と前に置くこともできます。前に置くか後ろに置くかで、動作が少し異なるので注意しましょう。
インクリメントは演算子を使った式なので、変数の値を変えるだけではなく、値を返します。返される値は、前に演算子を置くと元の変数の値、後ろに置くと1を加算または減算した後の値となります。上記例のように単独で使う場合、返される値は使われないため違いはありませんが、他の変数に代入する場合には違い出て来ますので注意しましょう。
次のようなコードを実行すると違いが分かりやすいでしょう。実行する前に結果を予想してみてください。
<?php $num1 = 1; $num2 = 1; $ans1 = $num1++; // 【1】 $ans2 = ++$num2; // 【2】 print("num1:ans1=".$num1.":".$ans1); // 【3】 print("<br>num2:ans2=".$num2.":".$ans2); // 【4】
実行結果は以下の通りです。
num1:ans1=2:1 num2:ans2=2:2
いかがでしたか? 予想通りでしたか?
$num1も$num2も「+1」されますので、表示時点での値は「2」です。ポイントは、$ans1や$ans2に代入されるタイミングです。後置の++は$ans1に代入してから+1されます(リスト4の【1】)。結果、【3】は「2:1」となっています。一方、前置の場合は(リスト4の【2】)、+1されてから$ans2に代入されています。そのため、【4】の表示結果は「2:2」となります。
いずれにしても、これらは、慣れないと読みにくいものです。読みやすいコードを書くという観点では、こういったインクリメントと代入を合わせた使い方はせずに、単独で使うにとどめておくという判断も有効です。
ここからはwhileループの解説に進みましょう。まずは、一定の回数を繰り返す例を示します。以下の例は10回繰り返す例です。
<?php $i = 1; while($i <= 10) { // 【1】 print($i."<br>"); // 【2】 $i++; // 【3】 }
実行結果は以下の通りです。
1 2 3 4 5 6 7 8 9 10
【2】と【3】の波かっこ内がループする内容で、「$i」の表示とインクリメントを行っています。つまり、$i変数でループ回数をカウントしているわけです。
【1】のwhileの後に続くかっこ内にあるのがループを継続するための条件です。リスト5では連載第4回で紹介した、大小を比較する比較演算子を使って、「$iが10以下のとき真となる」条件を設定しています。
この条件は波かっこ内を実行する前に評価され、真の場合にのみ波かっこ内を実行します。偽であればループ内を実行せず、while文を終了します。
$iは1から始まり、ループを1回実行するたび1ずつ加算されていきます。10回目の実行で$iが11になると、11回目の実行の前に行われる比較で偽となり、ループを終了するというわけです。
これを構文化すると、次のようになります。
while(条件) {
条件が正しいときにループしたい処理
}
例ではカウンター変数、つまり回数を条件にしましたが、条件は何であっても構いません。例えば、ファイルを1行ずつループで読み込み、ファイル末尾まで来たらループを終了する、といった処理はよく見られます。
if文で実行する文が1文の場合は波かっこを省略できることを「注意! if文での波かっこの省略」で紹介しましたが、while文でも同様です。
$i = 1; while($i <= 11) print($i."<br>");
文法的には正しいのですが、もし1文の場合であっても常に波かっこを使った方がよいでしょう。文を追加または削除するときのことを考えると、波かっこがある状態で統一されていた方が便利だからです。
ところで、今まで省略できると説明してきましたが、むしろif文やwhile文に続くのは1文のみといった方が正しいのです。「波かっこは複数の文を1文にまとめるためのもの」ということを踏まえると、このような仕様になっている理由が理解できます。
if文なども「ネスト」(入れ子)にすることができましたが、ループも入れ子にすることができます。
例として、1×1から9×9までの掛け算の結果、つまり、九九を表示することを考えてみます。まず1つ目の数字になる1〜9のループを作ります。
$i = 1; while($i <= 9) { $i++; }
次に、掛ける数字のループを内部に作り、表示を行います。つまり、以下のようなソースコードになります。
<?php $i = 1; while($i <= 9) { $j = 1; while($j <= 9) { $ans = $i * $j; print("{$i} * {$j} = {$ans}<br>"); $j++; } $i++; }
実行結果は以下の通りです。なお、長いので、途中を省略しています。
1 * 1 = 1 1 * 2 = 2 1 * 3 = 3 1 * 4 = 4 1 * 5 = 5 1 * 6 = 6 1 * 7 = 7 〜〜省略〜〜 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81
ところで、ここで使っている変数名の「$i」「$j」ですが、これは「ループカウンター」として使う変数名として慣例となっているものです。「$i」「$j」「$k」までがよく使われます。変数名は分かりやすい名前にするのが鉄則ではありますが、逆にこの名前を使うことでループカウンターであることが分かります。
ループについては解説しなければならない重要な構文がまだありますので、次回もループについて解説します。
【2014/5/14】初版公開(山口晴広,株式会社イメージズ・アンド・ワーズ)。
【2017/6/12】PHP 7.1含め2017年の情報に合うように更新(齊藤新三/山田祥寛(監修),WINGSプロジェクト)。
Copyright © ITmedia, Inc. All Rights Reserved.