PHP 入門

PHP while ループ

while ループは制御構造(コントロールストラクチャ)の一種で、指定した条件の評価結果が true(真)である限り、コードブロックを繰り返し実行します。あらかじめ反復回数が決まっているループとは異なり、while ループは「ファイルの末尾に達するまでデータを読み込む」「特定のユーザー入力を待機する」といった、反復回数が事前に予測できないシナリオに最適な設計となっています。

1. while ループの構造を解剖する

この構造は、主に ブーリアン式(条件)コードブロック(ループ体) の 2 つの要素で構成されます。各イテレーション(反復)が始まる前に、PHP はその条件を評価します。条件が true であれば、波括弧内のコードが実行されます。false であれば、プログラムはループを完全にスキップし、直後の行から実行を継続します。

<?php
$counter = 1;

while ($counter <= 5) {
    echo "現在のイテレーション回数:$counter <br>";
    $counter++; // 変数をインクリメント。これが最終的にループを抜ける鍵となります
}
?>

上記の例では、条件 $counter <= 5 が各ループサイクルの開始時にチェックされます。ここで使用されている ++ 演算子(インクリメント)は極めて重要です。これがないと、$counter は永久に 1 のままとなり、無限ループを引き起こします。その結果、スクリプトのクラッシュやサーバーのタイムアウトを招く恐れがあります。

2. 無限ループとロジカルなリスク

ループ条件が false にならない場合に発生するのが、無限ループ(Infinite Loop)です。長時間実行されるバックグラウンドワーカーやゲームエンジンなど、一部の高度なシナリオで意図的に使用されることもありますが、通常はロジカルエラー(論理ミス)によって引き起こされます。つまり、ループの終了条件がいつまでも満たされない状態です。

データベースのレコードを処理するシナリオを想像してみましょう。

<?php
$hasMoreRecords = true;

while ($hasMoreRecords) {
    // この関数がデータベースカーソルをチェックし、次のレコードを取得すると仮定
    $record = getNextRecord();
    
    if (!$record) {
        $hasMoreRecords = false; // セーフティブレーキ:レコードがない場合に条件ステータスを変更
    } else {
        process($record); // レコードを処理
    }
}
?>

もしデータベースから結果が返ってこなかったときに $hasMoreRecords のステータスを更新し忘れると、スクリプトは空の値を処理しようと永遠に動き続けます。すべての while ループにおいて、コードブロックの内部に明確で到達可能な「終了パス」を確保することが不可欠です。

3. 実行フローの視覚化

while ループは、本質的に「門番のいるチェックポイント」です。ゲートが開いている(条件が真)ときだけ実行フローがループ内に入ることができ、内部のタスクを完了するたびに、再びチェックを受けるために門番のところへ戻る必要があります。

  1. ループ開始 → 条件は true ですか?
  2. Yes(はい): コードブロックを実行 → ループ変数を更新 → 条件チェックに戻る。
  3. No(いいえ): ループを終了 → スクリプトの後続コードへ進む。

4. 実戦的な応用:動的なデータの読み込み

ある貯蓄口座において、特定の月利で残高が 2 倍になるまでにどれくらいの期間(月数)が必要かを計算するとします。この場合、正確な月数は事前には分かりませんが、目指すべき「ゴール」は決まっています。これこそが while ループの真骨頂を発揮するシナリオです。

<?php
$balance = 1000;      // 初期残高
$target = 2000;       // 目標残高(2倍)
$interestRate = 0.05; // 月利 5%
$months = 0;          // 経過月数のカウンタ

while ($balance < $target) {
    $balance += ($balance * $interestRate); // 毎月利息を加算
    $months++; // 月数をカウントアップ
}

echo "目標残高に達するまでには $months ヶ月必要です。";
?>

残高の増加は常に変動する $balance の値に依存しているため、while 構造はこのロジックをエレガントに処理します。開発者が手動で正確な反復回数を指定する必要は一切ありません。