PHP While循环

循环是编程中一种重要的控制结构,它允许我们重复执行一段代码多次。PHP提供了几种循环结构,其中While循环是最基本的一种。本教程将详细介绍PHP中While循环的使用方法、技巧和实际应用场景。

PHP循环结构概述

PHP提供了以下几种循环结构:

  • While循环 - 在条件为真时重复执行代码块
  • Do-While循环 - 至少执行一次代码块,然后在条件为真时重复执行
  • For循环 - 执行指定次数的代码块
  • Foreach循环 - 遍历数组中的每个元素

While循环

While循环是PHP中最基本的循环结构。它会在指定条件为真时重复执行代码块。

While循环的语法

while (条件) {
    // 要重复执行的代码
}

While循环的工作原理:

  1. 首先计算条件表达式的值
  2. 如果条件为真(TRUE),则执行循环体中的代码
  3. 执行完循环体后,再次计算条件表达式的值
  4. 如果条件仍然为真,则继续执行循环体
  5. 直到条件为假(FALSE)时,循环结束,程序继续执行循环后的代码

While循环示例

<?php
// 打印1到10的数字
$i = 1;
while ($i <= 10) {
    echo $i . " ";
    $i++;
}// 输出: 1 2 3 4 5 6 7 8 9 10
?>

在这个例子中:

  • 我们初始化变量$i为1
  • While循环检查$i是否小于或等于10
  • 如果条件为真,就打印$i的值,然后将$i增加1
  • 当$i变成11时,条件变为假,循环结束

计算1到100的和

<?php
// 计算1到100的和
$sum = 0;
$i = 1;

while ($i <= 100) {
    $sum += $i;
    $i++;
}

echo "1到100的和是: " . $sum; // 输出: 1到100的和是: 5050
?>

遍历数组

<?php
// 使用while循环遍历数组
$fruits = array("苹果", "香蕉", "橙子", "葡萄", "草莓");
$index = 0;
$length = count($fruits);

while ($index < $length) {
    echo $fruits[$index] . "<br>";
    $index++;
}
?>

Do-While循环

Do-While循环是While循环的一种变体。它会先执行一次代码块,然后在条件为真时重复执行。这意味着Do-While循环至少会执行一次,无论条件是否为真。

Do-While循环的语法

do {
    // 要执行的代码
} while (条件);

Do-While循环的工作原理:

  1. 首先执行循环体中的代码
  2. 然后计算条件表达式的值
  3. 如果条件为真(TRUE),则再次执行循环体
  4. 直到条件为假(FALSE)时,循环结束

Do-While循环示例

<?php
// 打印1到10的数字(使用do-while循环)
$i = 1;

do {
    echo $i . " ";
    $i++;
} while ($i <= 10); // 输出: 1 2 3 4 5 6 7 8 9 10
?>

这个例子与前面的While循环示例功能相同,但使用了Do-While循环结构。

条件为假的Do-While循环

<?php
// 即使条件一开始就是假,do-while循环也会执行一次
$i = 11;

do {
    echo $i . " ";
    $i++;
} while ($i <= 10); // 输出: 11
?>

在这个例子中,虽然条件$i <= 10一开始就是假的,但由于使用的是Do-While循环,代码块仍然会执行一次。

Break语句

Break语句用于立即退出当前的循环结构(While、Do-While、For、Foreach等)。当循环中遇到Break语句时,循环将立即终止,程序继续执行循环后的代码。

Break语句示例

<?php
// 使用break语句跳出循环
$i = 1;

while ($i <= 100) {
    echo $i . " ";
    
    // 当$i等于20时跳出循环
    if ($i == 20) {
        break;
    }
    
    $i++;
}// 输出: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
?>

在这个例子中,当$i的值等于20时,Break语句会立即终止循环,即使循环条件$i <= 100仍然为真。

在嵌套循环中使用Break

<?php
// 在嵌套循环中使用break(只跳出内层循环)
$i = 1;

while ($i <= 5) {
    echo "外层循环: " . $i . "<br>";
    
    $j = 1;
    while ($j <= 5) {
        echo "内层循环: " . $j . "<br>";
        
        // 当$j等于3时跳出内层循环
        if ($j == 3) {
            break;
        }
        
        $j++;
    }
    
    $i++;
}
?>

在嵌套循环中,Break语句默认只会跳出当前所在的循环(即内层循环),外层循环会继续执行。

Continue语句

Continue语句用于跳过当前循环迭代的剩余代码,并开始下一次迭代。当循环中遇到Continue语句时,程序会跳过当前迭代中Continue语句之后的代码,直接进入下一次迭代。

Continue语句示例

<?php
// 使用continue语句跳过偶数
$i = 1;

while ($i <= 10) {
    // 如果$i是偶数,跳过当前迭代
    if ($i % 2 == 0) {
        $i++;
        continue;
    }
    
    echo $i . " ";
    $i++;
}// 输出: 1 3 5 7 9
?>

在这个例子中,当$i的值是偶数时,Continue语句会跳过当前迭代中Continue语句之后的代码(即echo语句),直接进入下一次迭代。因此,只有奇数会被打印出来。

在嵌套循环中使用Continue

<?php
// 在嵌套循环中使用continue(只跳过内层循环的当前迭代)
$i = 1;

while ($i <= 5) {
    echo "外层循环: " . $i . "<br>";
    
    $j = 1;
    while ($j <= 5) {
        // 如果$j是偶数,跳过当前迭代
        if ($j % 2 == 0) {
            $j++;
            continue;
        }
        
        echo "内层循环: " . $j . "<br>";
        $j++;
    }
    
    $i++;
}
?>

在嵌套循环中,Continue语句默认只会跳过当前所在循环的当前迭代,不会影响外层循环。

无限循环

无限循环是指条件永远为真的循环。在某些情况下,无限循环是有用的,但必须确保在循环体中提供一个退出机制(通常使用Break语句),否则程序将陷入死循环。

无限循环示例

<?php
// 无限循环示例(使用break退出)
$i = 1;

while (true) {
    echo $i . " ";
    
    // 当$i等于10时退出循环
    if ($i == 10) {
        break;
    }
    
    $i++;
}// 输出: 1 2 3 4 5 6 7 8 9 10
?>

在这个例子中,我们使用了条件为true的While循环,这意味着循环会一直执行下去。但是,我们在循环体中提供了一个退出机制,当$i等于10时,使用Break语句退出循环。

PHP While循环的最佳实践

  1. 确保循环条件最终会变为假:在使用While循环时,一定要确保循环条件最终会变为假,否则循环将无限执行下去,导致程序崩溃。
  2. 避免死循环:如果使用无限循环(条件为true),一定要在循环体中提供一个明确的退出机制(通常使用Break语句)。
  3. 选择合适的循环类型:根据具体的需求选择合适的循环类型。如果需要至少执行一次循环,应使用Do-While循环;如果需要遍历数组,应使用Foreach循环;如果知道循环次数,应使用For循环。
  4. 保持循环体简洁:尽量保持循环体简洁明了,如果循环体过于复杂,可以考虑将部分代码提取到函数中。
  5. 避免在循环中修改循环条件相关的变量:除非必要,否则不要在循环体中修改与循环条件相关的变量,这可能导致循环行为变得难以预测。
  6. 使用适当的缩进和格式:正确的缩进和格式可以使循环结构更加清晰易懂,便于阅读和维护。

PHP While循环综合示例

<?php
// 1. 简单计数器

echo "<h4>1. 简单计数器</h4>";

// 从1数到10
$count = 1;
while ($count <= 10) {
    echo "计数: " . $count . "<br>";
    $count++;
}

// 2. 倒计时

echo "<h4>2. 倒计时</h4>";

// 从10倒数到1
$countdown = 10;
while ($countdown >= 1) {
    echo "倒计时: " . $countdown . "<br>";
    $countdown--;
}
echo "开始!<br>";

// 3. 计算阶乘

echo "<h4>3. 计算阶乘</h4>";

function calculate_factorial($n) {
    // 检查输入是否有效
    if (!is_int($n) || $n < 0) {
        return "无效输入:请输入非负整数";
    }
    
    // 特殊情况:0的阶乘是1
    if ($n == 0) {
        return 1;
    }
    
    // 使用while循环计算阶乘
    $result = 1;
    $i = 1;
    
    while ($i <= $n) {
        $result *= $i;
        $i++;
    }
    
    return $result;
}

// 测试阶乘函数
$number = 5;
echo "$number 的阶乘是: " . calculate_factorial($number) . "<br>";
// 输出: 5 的阶乘是: 120

// 4. 生成斐波那契数列

echo "<h4>4. 生成斐波那契数列</h4>";

function generate_fibonacci($n) {
    // 检查输入是否有效
    if (!is_int($n) || $n <= 0) {
        return "无效输入:请输入正整数";
    }
    
    // 处理特殊情况
    if ($n == 1) {
        return array(0);
    }
    
    // 初始化斐波那契数列
    $fibonacci = array(0, 1);
    $i = 2;
    
    // 使用while循环生成斐波那契数列
    while ($i < $n) {
        $fibonacci[] = $fibonacci[$i-1] + $fibonacci[$i-2];
        $i++;
    }
    
    return $fibonacci;
}

// 生成前10个斐波那契数
$fibonacci_sequence = generate_fibonacci(10);
echo "前10个斐波那契数: " . implode(", ", $fibonacci_sequence) . "<br>";
// 输出: 前10个斐波那契数: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

// 5. 猜数字游戏

echo "<h4>5. 猜数字游戏</h4>";

session_start();

// 如果是第一次访问页面,生成随机数
if (!isset($_SESSION['random_number'])) {
    $_SESSION['random_number'] = rand(1, 100);
    $_SESSION['attempts'] = 0;
}

// 处理表单提交
if (isset($_POST['guess'])) {
    $user_guess = intval($_POST['guess']);
    $_SESSION['attempts']++;
    
    if ($user_guess < $_SESSION['random_number']) {
        echo "太小了!请再试一次。<br>";
    } else if ($user_guess > $_SESSION['random_number']) {
        echo "太大了!请再试一次。<br>";
    } else {
        echo "恭喜你猜对了!数字是 " . $_SESSION['random_number'] . ".<br>";
        echo "你用了 " . $_SESSION['attempts'] . " 次尝试。<br>";
        
        // 重置游戏
        unset($_SESSION['random_number']);
        unset($_SESSION['attempts']);
        echo "<a href='" . htmlspecialchars($_SERVER['PHP_SELF']) . "'>再玩一次</a>";
        exit;
    }
}

// 显示猜数字表单
if (isset($_SESSION['random_number'])) {
    echo '<form method="post" action="' . htmlspecialchars($_SERVER['PHP_SELF']) . '">
        我想了一个1到100之间的数字,你能猜出来吗?<br>
        你的猜测: <input type="number" name="guess" min="1" max="100" required>
        <input type="submit" value="猜一猜">
    </form>';
}

// 6. 遍历并处理数组

echo "<h4>6. 遍历并处理数组</h4>";

// 创建一个数字数组
$numbers = array(3, 8, 2, 7, 5, 1, 9, 4, 6);
echo "原始数组: " . implode(", ", $numbers) . "<br>";

// 找出最大值
$max_value = $numbers[0];
$i = 1;
$length = count($numbers);

while ($i < $length) {
    if ($numbers[$i] > $max_value) {
        $max_value = $numbers[$i];
    }
    $i++;
}
echo "数组中的最大值: " . $max_value . "<br>";

// 计算平均值
$sum = 0;
$i = 0;

while ($i < $length) {
    $sum += $numbers[$i];
    $i++;
}
$average = $sum / $length;
echo "数组的平均值: " . $average . "<br>";

// 7. 简单的计算器

echo "<h4>7. 简单的计算器</h4>";

// 处理计算器表单提交
if (isset($_POST['calculate'])) {
    $num1 = floatval($_POST['num1']);
    $num2 = floatval($_POST['num2']);
    $operation = $_POST['operation'];
    $result = 0;
    
    // 使用switch语句根据操作类型执行不同的计算
    switch ($operation) {
        case 'add':
            $result = $num1 + $num2;
            break;
        case 'subtract':
            $result = $num1 - $num2;
            break;
        case 'multiply':
            $result = $num1 * $num2;
            break;
        case 'divide':
            if ($num2 == 0) {
                echo "错误:除数不能为零!<br>";
            } else {
                $result = $num1 / $num2;
            }
            break;
        default:
            echo "错误:无效的操作!<br>";
    }
    
    if (isset($result)) {
        echo "计算结果: " . $result . "<br>";
    }
}

// 显示计算器表单
echo '<form method="post" action="' . htmlspecialchars($_SERVER['PHP_SELF']) . '">
    第一个数: <input type="number" name="num1" required><br>
    操作: 
    <select name="operation" required>
        <option value="add">+</option>
        <option value="subtract">-</option>
        <option value="multiply">*</option>
        <option value="divide">/</option>
    </select><br>
    第二个数: <input type="number" name="num2" required><br>
    <input type="submit" name="calculate" value="计算">
</form>';

// 8. 生成乘法表

echo "<h4>8. 生成乘法表</h4>";

function generate_multiplication_table($size) {
    // 检查输入是否有效
    if (!is_int($size) || $size < 1) {
        return "无效输入:请输入正整数";
    }
    
    echo "<table border='1' cellspacing='0' cellpadding='5'>";
    
    // 生成表头
    echo "<tr><th>X</th>";
    $i = 1;
    while ($i <= $size) {
        echo "<th>" . $i . "</th>";
        $i++;
    }
    echo "</tr>";
    
    // 生成乘法表内容
    $i = 1;
    while ($i <= $size) {
        echo "<tr><th>" . $i . "</th>";
        
        $j = 1;
        while ($j <= $size) {
            echo "<td>" . ($i * $j) . "</td>";
            $j++;
        }
        
        echo "</tr>";
        $i++;
    }
    
    echo "</table>";
}

// 生成5x5乘法表
generate_multiplication_table(5);

// 9. 简单的文件读取

echo "<h4>9. 简单的文件读取</h4>";

// 创建一个示例文件用于测试
$filename = 'example.txt';
$file_content = "这是第一行\n这是第二行\n这是第三行\n这是第四行\n这是第五行";
file_put_contents($filename, $file_content);

echo "文件内容: <br><pre>";

// 打开文件进行读取
$file_handle = fopen($filename, 'r');

// 使用while循环读取文件内容
while (!feof($file_handle)) {
    $line = fgets($file_handle);
    echo $line;
}

// 关闭文件
fclose($file_handle);

echo "</pre>";

// 删除测试文件
echo "<br>";
if (file_exists($filename)) {
    unlink($filename);
    echo "测试文件已删除。";
}

// 10. 简单的分页显示

echo "<h4>10. 简单的分页显示</h4>";

// 模拟数据
$items_per_page = 5;
$total_items = 23;
$total_pages = ceil($total_items / $items_per_page);

// 获取当前页码
$current_page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$current_page = max(1, min($current_page, $total_pages));

// 计算当前页的起始项和结束项
$start_item = ($current_page - 1) * $items_per_page + 1;
$end_item = min($current_page * $items_per_page, $total_items);

// 显示当前页的内容
$i = $start_item;
echo "第 $current_page 页 (共 $total_pages 页): <br>";
echo "显示第 $start_item 到 $end_item 项 (共 $total_items 项): <br>";
echo "<ul>";

while ($i <= $end_item) {
    echo "<li>项目 $i</li>";
    $i++;
}
echo "</ul>";

// 显示分页链接
echo "<div class='pagination'>";

// 显示上一页链接
if ($current_page > 1) {
    echo "<a href='?page=" . ($current_page - 1) . "'>上一页</a> ";
}

// 显示页码链接
$page_range = 2; // 当前页前后显示的页数
$start_page = max(1, $current_page - $page_range);
$end_page = min($total_pages, $current_page + $page_range);

$i = $start_page;
while ($i <= $end_page) {
    if ($i == $current_page) {
        echo "<span class='current-page'>$i</span> ";
    } else {
        echo "<a href='?page=$i'>$i</a> ";
    }
    $i++;
}

// 显示下一页链接
if ($current_page < $total_pages) {
    echo "<a href='?page=" . ($current_page + 1) . "'>下一页</a>";
}

echo "</div>";

// 11. 简单的用户输入验证

echo "<h4>11. 简单的用户输入验证</h4>";

// 模拟用户注册表单
if (isset($_POST['register'])) {
    $username = trim($_POST['username']);
    $email = trim($_POST['email']);
    $password = trim($_POST['password']);
    $confirm_password = trim($_POST['confirm_password']);
    
    $errors = array();
    
    // 验证用户名
    if (empty($username)) {
        $errors[] = "用户名不能为空";
    } else if (strlen($username) < 3) {
        $errors[] = "用户名至少需要3个字符";
    }
    
    // 验证电子邮件
    if (empty($email)) {
        $errors[] = "电子邮件不能为空";
    } else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors[] = "请输入有效的电子邮件地址";
    }
    
    // 验证密码
    if (empty($password)) {
        $errors[] = "密码不能为空";
    } else if (strlen($password) < 6) {
        $errors[] = "密码至少需要6个字符";
    }
    
    // 验证确认密码
    if (empty($confirm_password)) {
        $errors[] = "请确认密码";
    } else if ($password !== $confirm_password) {
        $errors[] = "两次输入的密码不一致";
    }
    
    // 显示验证结果
    if (count($errors) > 0) {
        echo "<div class='error-messages'>";
        echo "请修复以下错误:<br>";
        $i = 0;
        while ($i < count($errors)) {
            echo "- " . $errors[$i] . "<br>";
            $i++;
        }
        echo "</div>";
    } else {
        echo "<div class='success-message'>";
        echo "注册成功!<br>";
        echo "用户名: " . htmlspecialchars($username) . "<br>";
        echo "电子邮件: " . htmlspecialchars($email) . "<br>";
        echo "</div>";
    }
}

// 显示用户注册表单
echo '<form method="post" action="' . htmlspecialchars($_SERVER['PHP_SELF']) . '">
    用户名: <input type="text" name="username" value="' . (isset($_POST['username']) ? htmlspecialchars($_POST['username']) : '') . '"><br>
    电子邮件: <input type="email" name="email" value="' . (isset($_POST['email']) ? htmlspecialchars($_POST['email']) : '') . '"><br>
    密码: <input type="password" name="password"><br>
    确认密码: <input type="password" name="confirm_password"><br>
    <input type="submit" name="register" value="注册">
</form>';

// 12. 简单的投票系统

echo "<h4>12. 简单的投票系统</h4>";

session_start();

// 初始化投票选项
if (!isset($_SESSION['votes'])) {
    $_SESSION['votes'] = array(
        'option1' => 0,
        'option2' => 0,
        'option3' => 0
    );
}

// 初始化用户投票状态
if (!isset($_SESSION['has_voted'])) {
    $_SESSION['has_voted'] = false;
}

// 处理投票提交
if (isset($_POST['vote']) && !$_SESSION['has_voted']) {
    $selected_option = $_POST['option'];
    
    // 验证投票选项
    if (isset($_SESSION['votes'][$selected_option])) {
        $_SESSION['votes'][$selected_option]++;
        $_SESSION['has_voted'] = true;
        echo "投票成功!谢谢参与。<br>";
    } else {
        echo "无效的投票选项!<br>";
    }
} else if (isset($_POST['vote']) && $_SESSION['has_voted']) {
    echo "您已经投过票了!<br>";
}

// 显示投票结果
$total_votes = array_sum($_SESSION['votes']);
echo "投票结果: <br>";
echo "<ul>";

$options = array(
    'option1' => '选项1',
    'option2' => '选项2',
    'option3' => '选项3'
);

$i = 0;
$option_keys = array_keys($options);

while ($i < count($option_keys)) {
    $key = $option_keys[$i];
    $votes = $_SESSION['votes'][$key];
    $percentage = $total_votes > 0 ? round(($votes / $total_votes) * 100) : 0;
    
    echo "<li>" . $options[$key] . ": " . $votes . " 票 (" . $percentage . "%)</li>";
    $i++;
}

echo "</ul>";
echo "总票数: " . $total_votes . "<br><br>";

// 显示投票表单(如果用户还没有投票)
if (!$_SESSION['has_voted']) {
    echo '<form method="post" action="' . htmlspecialchars($_SERVER['PHP_SELF']) . '">
        请选择您的选项:<br>';
    
    $i = 0;
    while ($i < count($option_keys)) {
        $key = $option_keys[$i];
        echo '<input type="radio" name="option" value="' . $key . '" id="' . $key . '">
        <label for="' . $key . '">' . $options[$key] . '</label><br>';
        $i++;
    }
    
    echo '<input type="submit" name="vote" value="投票">
</form>';
}

// 提供重置投票的选项(实际应用中应该有更严格的权限控制)
echo "<br><a href='?reset_votes'>重置投票</a>";

// 处理重置投票
if (isset($_GET['reset_votes'])) {
    $_SESSION['votes'] = array(
        'option1' => 0,
        'option2' => 0,
        'option3' => 0
    );
    $_SESSION['has_voted'] = false;
    echo "<br>投票已重置!<br>";
}
?>