while (condition) { ... }は、条件がtrueである限りブロックを何度も実行します。条件は各回の前に確認されるので、最初からfalseなら本体は一度も実行されません。ループの中の何かが条件を変えなければ、ループは終わりません。
これはまさにwhile向きの問いです。何回繰り返すかは事前にわからず、いつ止めるかだけがわかっています。利率を変えて、もう一度実行してみてください。
do while:少なくとも1回は実行する
do { ... } while (condition);は本体のあとで条件を確認するので、本体は必ず1回実行されます。最後のセミコロンに注意してください。
典型的な使い方は「試してから確認する」です。6が出るまでサイコロを振る、使われていないコードができるまで生成する、などです。確認する対象ができる前に、最初の試行が必要になります。次のコードは実行のたびに結果が変わります。
breakを使うwhile (true)
終了条件を本体の途中で確認するほうが簡単な場合は、while (true)と書いてbreakで抜けます。continueはどのループとも同じく、次の確認へと飛びます。
array_shift()は配列が空になるとnullを返すので、これがもう1つの出口です。空の配列はfalseとみなされるので、同じループをwhile ($queue)と書くこともできます。
ファイルを1行ずつ読む
fgets()は1行ずつ返し、ファイルの終わりでfalseを返すので、そのままwhileループを動かせます。このブロックは先にファイルを書き込み、それから読み込みます。
$line = fgets($handle)を囲む括弧が重要です。先に代入が行われ、その結果がfalseと比較されます。単にtrueかどうかを判定する代わりに!== falseを使うと、0だけの最後の行(後ろに改行がない場合)でループが早く終わってしまうのを防げます。ファイル関数についてはfopen()のページで扱っています。
テンプレートでのwhileとendwhile
ifやforと同じく、whileにもHTML用のコロン形式があります:while (...):とendwhile;。次の例はPageタブにカウントダウンのリストを表示します。
よくあるミス:終わらないループ
カウンターは出口に向かって動かなければなりません。$i++を忘れたり、違う変数を変えたりすると、条件はずっとtrueのままです。Webサーバーでは、PHPはmax_execution_time(デフォルトで30秒)が経つと致命的エラーでスクリプトを止めます。コマンドラインでは止まりません。
// Never ends: $i is never changed
$i = 0;
while ($i < 3) {
echo $i;
}
外部のデータに依存するループ、たとえば呼び出しの再試行や結果のページ送りには、安全のための上限を設けておくと手軽な防御になります。
何回か実行してみてください。早く成功することもあればあきらめることもありますが、必ず終わります。繰り返す回数が事前にわかっているなら、開始、終了、刻みを1行で示せて間違えにくいforループを使いましょう。
よくある質問
PHPのwhileとdo whileの違いは何ですか?
whileは各回の前に条件を確認するので、本体が一度も実行されないことがあります。do { ... } while ($cond);は各回のあとに確認するので、本体は必ず1回は実行されます。do whileの条件のあとのセミコロンに注意してください。
PHPで終わらないwhileループを止めるには?
ループの中で、終了条件を満たしたらbreakで終わらせます:while (true) { ...; if ($done) { break; } }。breakがなく条件もfalseにならないループは、PHPのmax_execution_timeが止めるまで(Webリクエスト)、またはいつまでも(コマンドライン)実行されます。
PHPでforではなくwhileを使うのはどんなときですか?
何回繰り返せばよいかわからないときはwhileを使います。ファイルの終わりまで読む、成功するまで再試行する、空になるまでキューを処理する、などです。数えるときはforを、配列のすべての要素を順に見るときはforeachを使います。
PHPにdo untilループはありますか?
ありません。do whileで停止条件を否定します:do { $n++; } while (!($n >= 3));は$n >= 3がtrueになるまで実行されます。untilはPHPのキーワードではありません。