PHP while 迴圈

while 迴圈會在條件為 true 時重複執行程式碼區塊。當你不確定要執行多少次,只知道執行條件時,while 是很好的選擇。

while 語法

while (條件) {
    // 程式碼
}

只要條件為 true,程式碼就會持續執行:

<?php
$count = 1;

while ($count <= 5) {
    echo "第 $count 次\n";
    $count++;
}
?>

輸出:

第 1 次
第 2 次
第 3 次
第 4 次
第 5 次

執行流程

  1. 檢查條件是否為 true
  2. 如果為 true,執行程式碼區塊
  3. 回到步驟 1
  4. 如果為 false,跳出迴圈
<?php
$i = 1;

while ($i <= 3) {
    echo "i = $i\n";  // 執行 3 次
    $i++;
}

echo "迴圈結束,i = $i";  // i = 4
?>

do...while 語法

do...while 會先執行一次程式碼,再檢查條件。即使條件一開始就是 false,程式碼也會至少執行一次:

<?php
$count = 1;

do {
    echo "第 $count 次\n";
    $count++;
} while ($count <= 5);
?>

while vs do...while

<?php
$x = 10;

// while - 條件一開始就是 false,不會執行
while ($x < 5) {
    echo "while: $x\n";
    $x++;
}

// do...while - 會先執行一次,再檢查條件
$y = 10;

do {
    echo "do-while: $y\n";
    $y++;
} while ($y < 5);
// 輸出:do-while: 10
?>

無限迴圈

如果條件永遠為 true,會造成無限迴圈:

<?php
// 錯誤示範 - 無限迴圈
while (true) {
    echo "這會永遠執行...\n";
}

// 忘記更新條件變數也會造成無限迴圈
$i = 1;
while ($i <= 5) {
    echo $i;  // 忘記 $i++
}
?>
務必確保迴圈有終止條件,避免造成無限迴圈導致程式當機。

有意的無限迴圈

有時候會故意使用無限迴圈,搭配 break 跳出:

<?php
while (true) {
    $input = readline("請輸入指令(輸入 'quit' 離開):");
    
    if ($input === 'quit') {
        echo "再見!\n";
        break;
    }
    
    echo "你輸入了:$input\n";
}
?>

break 語句

break 用於立即跳出迴圈:

<?php
$count = 1;

while ($count <= 10) {
    if ($count === 5) {
        echo "到 5 了,跳出迴圈\n";
        break;
    }
    echo "count = $count\n";
    $count++;
}
// 只會輸出 1 到 4
?>

continue 語句

continue 用於跳過當前這次迭代,繼續下一次:

<?php
$count = 0;

while ($count < 10) {
    $count++;
    
    // 跳過偶數
    if ($count % 2 === 0) {
        continue;
    }
    
    echo "$count ";
}
// 輸出:1 3 5 7 9
?>

巢狀迴圈

迴圈可以巢狀使用:

<?php
$row = 1;

while ($row <= 3) {
    $col = 1;
    while ($col <= 3) {
        echo "($row, $col) ";
        $col++;
    }
    echo "\n";
    $row++;
}
?>

輸出:

(1, 1) (1, 2) (1, 3) 
(2, 1) (2, 2) (2, 3) 
(3, 1) (3, 2) (3, 3) 

跳出多層迴圈

使用 break n 跳出指定層數的迴圈:

<?php
$i = 1;

while ($i <= 3) {
    $j = 1;
    while ($j <= 3) {
        echo "($i, $j) ";
        if ($i === 2 && $j === 2) {
            echo "\n找到 (2, 2),跳出所有迴圈\n";
            break 2;  // 跳出 2 層迴圈
        }
        $j++;
    }
    echo "\n";
    $i++;
}
?>

替代語法

在 HTML 模板中使用替代語法:

<?php $items = ['蘋果', '香蕉', '橘子']; ?>
<?php $i = 0; ?>

<ul>
<?php while ($i < count($items)): ?>
    <li><?= $items[$i] ?></li>
    <?php $i++; ?>
<?php endwhile; ?>
</ul>

實際應用範例

讀取檔案

<?php
$file = fopen("data.txt", "r");

while (!feof($file)) {
    $line = fgets($file);
    echo $line;
}

fclose($file);
?>

資料庫查詢結果

<?php
$conn = mysqli_connect("localhost", "user", "pass", "database");
$result = mysqli_query($conn, "SELECT * FROM users");

while ($row = mysqli_fetch_assoc($result)) {
    echo "名稱:" . $row['name'] . "\n";
    echo "Email:" . $row['email'] . "\n";
    echo "---\n";
}

mysqli_close($conn);
?>

等待條件成立

<?php
$retries = 0;
$maxRetries = 5;
$success = false;

while (!$success && $retries < $maxRetries) {
    echo "嘗試第 " . ($retries + 1) . " 次...\n";
    
    // 模擬可能失敗的操作
    $success = (random_int(1, 3) === 1);
    
    if (!$success) {
        $retries++;
        sleep(1);  // 等待 1 秒後重試
    }
}

if ($success) {
    echo "操作成功!\n";
} else {
    echo "達到最大重試次數,操作失敗\n";
}
?>

處理佇列

<?php
$queue = ['任務1', '任務2', '任務3', '任務4'];

while (!empty($queue)) {
    $task = array_shift($queue);  // 取出第一個元素
    echo "處理:$task\n";
    
    // 處理任務...
    
    // 可能會新增更多任務
    if ($task === '任務2') {
        $queue[] = '新增的任務';
    }
}

echo "所有任務處理完成\n";
?>

數學運算:計算階乘

<?php
function factorial(int $n): int {
    if ($n < 0) {
        throw new InvalidArgumentException("階乘只能計算非負整數");
    }
    
    $result = 1;
    $i = 2;
    
    while ($i <= $n) {
        $result *= $i;
        $i++;
    }
    
    return $result;
}

echo factorial(5);  // 120 (5! = 5 × 4 × 3 × 2 × 1)
echo factorial(0);  // 1 (0! = 1)
?>

猜數字遊戲

<?php
$answer = random_int(1, 100);
$attempts = 0;

echo "猜一個 1 到 100 之間的數字\n";

do {
    $guess = (int) readline("你的猜測:");
    $attempts++;
    
    if ($guess < $answer) {
        echo "太小了!\n";
    } else if ($guess > $answer) {
        echo "太大了!\n";
    } else {
        echo "恭喜你猜對了!答案是 $answer\n";
        echo "你總共猜了 $attempts 次\n";
    }
} while ($guess !== $answer);
?>