循环是编程中的重要概念,它允许我们重复执行特定的代码块,直到满足特定条件为止。PHP 提供了多种循环结构来满足不同的编程需求。
在编程中,我们经常需要重复执行相同的代码块。循环语句可以帮助我们高效地完成这类任务,避免代码重复。
选择循环类型的建议:
While 循环会在指定条件为真时重复执行代码块。它在每次迭代前检查条件,如果条件为假,循环将不会执行。
while (condition) {
// 要执行的代码
}
<?php
$i = 1;
while ($i <= 5) {
echo "数字是: " . $i . "<br>";
$i++;
}
?>
数字是: 1 数字是: 2 数字是: 3 数字是: 4 数字是: 5
<?php
// 模拟用户输入验证
$validInput = false;
$attempts = 0;
while (!$validInput && $attempts < 3) {
$attempts++;
// 模拟获取用户输入
$userInput = "admin123"; // 假设这是用户输入
if ($userInput === "admin123") {
$validInput = true;
echo "登录成功!<br>";
} else {
echo "密码错误,请重试(尝试次数: $attempts/3)<br>";
}
}
if (!$validInput) {
echo "登录失败,请稍后再试。<br>";
}
?>
Do...While 循环会先执行一次代码块,然后在指定条件为真时重复循环。这意味着循环体至少会执行一次。
do {
// 要执行的代码
} while (condition);
<?php
$i = 6;
do {
echo "数字是: " . $i . "<br>";
$i++;
} while ($i <= 5);
?>
数字是: 6
注意:即使条件 $i <= 5 一开始就为假,循环体仍然执行了一次。
<?php
// 模拟简单的菜单系统
$choice = "";
$running = true;
do {
// 显示菜单
echo "=== 菜单系统 ===<br>";
echo "1. 查看信息<br>";
echo "2. 修改设置<br>";
echo "3. 退出系统<br>";
echo "请选择 (1-3): ";
// 模拟用户选择
$choice = "2"; // 第一次选择
echo $choice . "<br>";
switch ($choice) {
case "1":
echo "显示系统信息...<br><br>";
break;
case "2":
echo "进入设置页面...<br><br>";
break;
case "3":
echo "系统退出中...<br>";
$running = false;
break;
default:
echo "无效选择,请重试。<br><br>";
}
// 模拟第二次选择为退出
if ($choice === "2") {
$choice = "3";
echo "请选择 (1-3): " . $choice . "<br>";
echo "系统退出中...<br>";
$running = false;
}
} while ($running);
?>
| 特性 | While 循环 | Do...While 循环 |
|---|---|---|
| 条件检查时机 | 循环开始前检查 | 循环结束后检查 |
| 最少执行次数 | 0 次(条件为假时) | 1 次(无论条件真假) |
| 适用场景 | 条件可能一开始就不满足的情况 | 至少需要执行一次的情况 |
| 语法结构 | while (条件) { ... } |
do { ... } while (条件); |
<?php
// 使用 while 循环
echo "=== While 循环 ===<br>";
$counter = 1;
while ($counter <= 3) {
echo "计数: " . $counter . "<br>";
$counter++;
}
echo "<br>";
// 使用 do...while 循环实现相同功能
echo "=== Do...While 循环 ===<br>";
$counter = 1;
do {
echo "计数: " . $counter . "<br>";
$counter++;
} while ($counter <= 3);
?>
=== While 循环 === 计数: 1 计数: 2 计数: 3 === Do...While 循环 === 计数: 1 计数: 2 计数: 3
PHP 提供了两个重要的循环控制语句:break 和 continue。
break 用于完全终止循环的执行。
<?php
$i = 1;
while ($i <= 10) {
if ($i == 5) {
echo "遇到 5,终止循环<br>";
break;
}
echo "当前数字: " . $i . "<br>";
$i++;
}
echo "循环结束后的代码<br>";
?>
continue 用于跳过当前循环迭代,继续执行下一次循环。
<?php
$i = 0;
while ($i < 5) {
$i++;
if ($i == 3) {
echo "跳过数字 3<br>";
continue;
}
echo "当前数字: " . $i . "<br>";
}
?>
在嵌套循环中,可以指定要跳出或继续的循环层级。
<?php
$i = 1;
while ($i <= 3) {
echo "外层循环: $i<br>";
$j = 1;
while ($j <= 3) {
if ($i == 2 && $j == 2) {
echo "跳出外层循环<br>";
break 2; // 跳出2层循环
}
echo "内层循环: $j<br>";
$j++;
}
$i++;
}
echo "程序结束<br>";
?>
<?php
// 模拟文件读取
$fileLines = [
"第一行内容",
"第二行内容",
"第三行内容",
"第四行内容",
"第五行内容"
];
echo "=== 文件内容 ===<br>";
$lineNumber = 0;
while ($lineNumber < count($fileLines)) {
echo "第 " . ($lineNumber + 1) . " 行: " . $fileLines[$lineNumber] . "<br>";
$lineNumber++;
}
// 实际文件读取的伪代码
/*
$handle = fopen("data.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// 处理每一行
echo $line . "<br>";
}
fclose($handle);
}
*/
?>
<?php
// 用户注册验证系统
function validateRegistration() {
$valid = false;
$attempts = 0;
$maxAttempts = 3;
while (!$valid && $attempts < $maxAttempts) {
$attempts++;
// 模拟用户输入
$username = "user123";
$email = "user@example.com";
$password = "Password123";
$errors = [];
// 用户名验证
if (strlen($username) < 3) {
$errors[] = "用户名至少需要3个字符";
}
// 邮箱验证
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "邮箱格式不正确";
}
// 密码验证
if (strlen($password) < 8) {
$errors[] = "密码至少需要8个字符";
}
if (empty($errors)) {
$valid = true;
echo "注册成功!<br>";
return true;
} else {
echo "尝试 $attempts/$maxAttempts - 验证失败:<br>";
foreach ($errors as $error) {
echo "- $error<br>";
}
echo "<br>";
}
// 模拟第二次尝试成功
if ($attempts == 1) {
$username = "validuser";
$password = "SecurePass123";
}
}
if (!$valid) {
echo "注册失败,请稍后再试。<br>";
return false;
}
}
validateRegistration();
?>
<?php
// 猜数字游戏
function guessNumberGame() {
$targetNumber = rand(1, 10); // 随机生成1-10的数字
$attempts = 0;
$maxAttempts = 3;
$guessed = false;
echo "=== 猜数字游戏 ===<br>";
echo "我已经想了一个1-10之间的数字,你有 $maxAttempts 次机会猜中它。<br><br>";
while (!$guessed && $attempts < $maxAttempts) {
$attempts++;
// 模拟用户猜测
$guess = ($attempts == 1) ? 5 : 7; // 第一次猜5,第二次猜7
echo "第 $attempts 次猜测: $guess<br>";
if ($guess == $targetNumber) {
$guessed = true;
echo "恭喜!你猜对了!<br>";
} elseif ($guess < $targetNumber) {
echo "太小了,请猜大一点的数字。<br><br>";
} else {
echo "太大了,请猜小一点的数字。<br><br>";
}
// 设置目标数字为7,让第二次猜中
$targetNumber = 7;
}
if (!$guessed) {
echo "很遗憾,游戏结束!正确的数字是: $targetNumber<br>";
}
}
guessNumberGame();
?>
无限循环是指循环条件始终为真,导致循环永远无法结束的情况。这会导致程序卡死或消耗大量资源。
<?php
// 错误示例1:忘记更新计数器
/*
$i = 1;
while ($i <= 5) {
echo "数字: $i<br>";
// 忘记 $i++,导致 $i 始终为1,循环永不结束
}
*/
// 错误示例2:条件永远为真
/*
while (true) {
echo "这是一个无限循环<br>";
// 没有 break 语句
}
*/
// 正确的做法:确保循环条件能够变为假
$i = 1;
while ($i <= 5) {
echo "数字: $i<br>";
$i++; // 重要:更新循环变量
}
// 或者使用 break 提供退出机制
$counter = 0;
while (true) {
$counter++;
echo "循环执行中... ($counter)<br>";
if ($counter >= 5) {
break; // 提供退出条件
}
}
?>
防止无限循环的最佳实践:
<?php
// 优化前:在循环内进行重复计算
$data = [1, 2, 3, 4, 5];
$i = 0;
while ($i < count($data)) { // count() 在每次迭代中都会执行
echo "元素: " . $data[$i] . "<br>";
$i++;
}
echo "<br>";
// 优化后:预先计算循环次数
$data = [1, 2, 3, 4, 5];
$count = count($data); // 预先计算
$i = 0;
while ($i < $count) {
echo "元素: " . $data[$i] . "<br>";
$i++;
}
?>
<?php
// 场景1:遍历已知长度的数组 - 使用 for 循环更合适
$items = ['a', 'b', 'c', 'd'];
for ($i = 0; $i < count($items); $i++) {
echo $items[$i] . "<br>";
}
echo "<br>";
// 场景2:条件循环 - 使用 while 循环
$userLoggedIn = true;
$loginAttempts = 0;
while ($userLoggedIn && $loginAttempts < 5) {
// 处理用户会话
$loginAttempts++;
if ($loginAttempts >= 3) {
$userLoggedIn = false; // 模拟登出
}
}
echo "用户会话处理完成<br>";
// 场景3:至少执行一次 - 使用 do...while
$dataAvailable = false;
do {
// 尝试获取数据
$dataAvailable = true; // 模拟成功获取数据
echo "数据获取成功<br>";
} while (!$dataAvailable);
?>
break 完全终止循环,使用 continue 跳过当前迭代