Skip to content

for 循环

for 循环是 PHP 中最常用的循环结构之一,它将初始化、条件判断和递增操作整合在一个语句中。for 循环特别适合迭代次数已知的场景,如遍历数字序列、固定长度的数组等。

前置知识

基础概念

for 循环由三个部分组成:

  1. 初始化(Initialization):在循环开始前执行一次,通常用于设置计数器变量。
  2. 条件(Condition):在每次迭代开始前判断,为 true 则执行循环体,为 false 则退出。
  3. 递增(Increment):在每次循环体执行完毕后执行,通常用于更新计数器。

执行顺序

for 循环的执行顺序:初始化 -> 条件判断 -> 循环体 -> 递增 -> 条件判断 -> 循环体 -> 递增 -> ... 直到条件为 false

语法结构

基本 for 语法

php
<?php
declare(strict_types=1);

// 基本 for 循环
for ($i = 1; $i <= 5; $i++) {
    echo "i = {$i}\n";
}
// 输出:
// i = 1
// i = 2
// i = 3
// i = 4
// i = 5

for 循环的三个表达式都可以省略

php
<?php
declare(strict_types=1);

// 省略初始化(在外部初始化)
$i = 0;
for (; $i < 3; $i++) {
    echo $i . " ";
}
echo "\n";

// 省略条件(需要在循环体中 break)
for ($i = 0; ; $i++) {
    if ($i >= 3) {
        break;
    }
    echo $i . " ";
}
echo "\n";

// 省略递增(在循环体中递增)
for ($i = 0; $i < 3; ) {
    echo $i . " ";
    $i++;
}
echo "\n";

for 的替代语法

php
<?php
declare(strict_types=1);

echo "<ul>\n";
for ($i = 1; $i <= 5; $i++):
    echo "<li>第 {$i} 项</li>\n";
endfor;
echo "</ul>\n";

详细说明

多重初始化和递增

for 循环的初始化和递增部分可以用逗号分隔多个表达式。

php
<?php
declare(strict_types=1);

// 多重初始化和递增
for ($i = 0, $j = 10; $i < $j; $i++, $j--) {
    echo "i = {$i}, j = {$j}\n";
}
// 输出:
// i = 0, j = 10
// i = 1, j = 9
// i = 2, j = 8
// i = 3, j = 7
// i = 4, j = 6

嵌套 for 循环

for 循环可以嵌套使用,内层循环在外层循环的每次迭代中完整执行。

php
<?php
declare(strict_types=1);

// 嵌套循环:遍历二维数组
$matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
];

for ($row = 0; $row < count($matrix); $row++) {
    for ($col = 0; $col < count($matrix[$row]); $col++) {
        echo $matrix[$row][$col] . " ";
    }
    echo "\n";
}
// 输出:
// 1 2 3
// 4 5 6
// 7 8 9

遍历数组索引

虽然 foreach 更适合遍历数组,但 for 循环在需要索引的情况下也很实用。

php
<?php
declare(strict_types=1);

$colors = ['红色', '绿色', '蓝色', '黄色', '紫色'];

for ($i = 0; $i < count($colors); $i++) {
    echo "索引 {$i}:{$colors[$i]}\n";
}
// 输出:
// 索引 0:红色
// 索引 1:绿色
// 索引 2:蓝色
// 索引 3:黄色
// 索引 4:紫色

for 循环中使用 continue

php
<?php
declare(strict_types=1);

// 使用 continue 跳过偶数
for ($i = 1; $i <= 10; $i++) {
    if ($i % 2 === 0) {
        continue; // 跳过偶数
    }
    echo $i . " ";
}
echo "\n";
// 输出:1 3 5 7 9

复杂的递增表达式

递增部分不一定是简单的 ++,可以是任意表达式。

php
<?php
declare(strict_types=1);

// 使用乘法递增(指数增长)
for ($i = 1; $i <= 1000; $i *= 2) {
    echo $i . " ";
}
echo "\n";
// 输出:1 2 4 8 16 32 64 128 256 512

实战示例

九九乘法表

for 循环嵌套的经典实战示例——生成九九乘法表。

php
<?php
declare(strict_types=1);

function printMultiplicationTable(): void
{
    echo "===== 九九乘法表 =====\n\n";

    for ($i = 1; $i <= 9; $i++) {
        for ($j = 1; $j <= $i; $j++) {
            $product = $i * $j;
            printf("%d x %d = %-4d", $j, $i, $product);
        }
        echo "\n";
    }
}

printMultiplicationTable();
// 输出:
// ===== 九九乘法表 =====
//
// 1 x 1 = 1
// 1 x 2 = 2   2 x 2 = 4
// 1 x 3 = 3   2 x 3 = 6   3 x 3 = 9
// 1 x 4 = 4   2 x 4 = 8   3 x 4 = 12  4 x 4 = 16
// ... 以此类推

HTML 表格生成

php
<?php
declare(strict_types=1);

function generateTimesTable(int $size = 10): string
{
    $html = "<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\">\n";
    $html .= "  <tr>\n    <th>&times;</th>\n";

    for ($col = 1; $col <= $size; $col++) {
        $html .= "    <th>{$col}</th>\n";
    }
    $html .= "  </tr>\n";

    for ($row = 1; $row <= $size; $row++) {
        $html .= "  <tr>\n";
        $html .= "    <th>{$row}</th>\n";

        for ($col = 1; $col <= $size; $col++) {
            $product = $row * $col;
            $highlight = ($row === $col) ? ' style="background:#ffffcc"' : '';
            $html .= "    <td{$highlight}>{$product}</td>\n";
        }

        $html .= "  </tr>\n";
    }

    $html .= "</table>\n";
    return $html;
}

echo generateTimesTable(5);

分页数据生成

php
<?php
declare(strict_types=1);

function generatePagination(int $totalItems, int $perPage, int $currentPage): array
{
    $totalPages = (int) ceil($totalItems / $perPage);
    $pages = [];

    for ($page = 1; $page <= $totalPages; $page++) {
        $pages[] = [
            'number'  => $page,
            'active'  => $page === $currentPage,
            'offset'  => ($page - 1) * $perPage,
        ];
    }

    return $pages;
}

$pagination = generatePagination(55, 10, 3);

echo "分页导航(共 {$pagination[count($pagination)-1]['number']} 页):\n";
foreach ($pagination as $page) {
    $marker = $page['active'] ? ' [当前]' : '';
    echo "  第 {$page['number']} 页{$marker}\n";
}

for vs foreach vs while

循环类型最佳场景特点
for已知迭代次数、需要索引初始化/条件/递增一体化
foreach遍历数组/对象自动迭代,无需手动管理索引
while条件驱动的迭代灵活,适合未知次数的循环
do-while至少执行一次先执行后判断

注意事项

  1. count() 放在条件中的性能问题:在 for 循环条件中直接使用 count($array) 不会导致性能问题,因为 PHP 会在每次迭代中重新计算。但为了代码清晰,可以先将结果缓存到变量中。

  2. 修改循环变量:在循环体内修改 $i 可能导致意外的行为,建议保持循环变量的递增/递减逻辑简单明确。

  3. 浮点数作为循环变量:浮点数精度问题可能导致循环次数不符合预期,建议使用整数循环变量。

  4. 无限循环:省略条件或条件永远为 true 时,for 循环也会变成无限循环,需配合 break 使用。

最佳实践

  1. 使用有意义的变量名:除了简单的 $i$j,在复杂循环中使用描述性的变量名(如 $rowIndex$columnIndex)。

  2. 避免在循环体中修改数组长度:在 for 循环中遍历数组时,如果循环体内增删元素,可能导致跳过或重复处理。

  3. 优先使用 foreach 遍历数组:当不需要索引或需要遍历关联数组时,foreach 是更好的选择。

  4. 控制嵌套层级:超过两层嵌套的 for 循环通常意味着需要重构,考虑提取函数或使用其他数据结构。

  5. 限制循环次数:对于可能产生大量迭代的循环,设置合理的上限以避免性能问题。

下一节

数组遍历最常用的方式是 foreach 循环。接下来学习 foreach 循环

进阶用法

调试与测试技巧

php
<?php
declare(strict_types=1);

// 单元测试辅助函数
function createTestResource(): mixed
{
    return match (true) {
        default => new stdClass(),
    };
}

// 调试输出函数
function debugOutput(mixed , string  = ''): void
{
     =  ? ": " : '';
     .= print_r(, true);
    fwrite(STDERR,  . "\n");
}

// 性能基准测试
function benchmark(callable , int  = 1000): float
{
     = hrtime(true);
    for ($i = 0; $i < $iterations; $i++) {
        $fn();
    }
    return (hrtime(true) - $start) / 1e9;
}

日志记录实践

php
<?php
declare(strict_types=1);

/**
 * 简易日志记录器
 */
class SimpleLogger
{
    private string $logFile;
    private string $level = 'INFO';

    public function __construct(string $logFile)
    {
        $this->logFile = $logFile;
    }

    public function info(string $message, array $context = []): void
    {
        $this->log('INFO', $message, $context);
    }

    public function warning(string $message, array $context = []): void
    {
        $this->log('WARNING', $message, $context);
    }

    public function error(string $message, array $context = []): void
    {
        $this->log('ERROR', $message, $context);
    }

    private function log(string $level, string $message, array $context): void
    {
        $timestamp = date('Y-m-d H:i:s');
        $contextStr = $context ? ' ' . json_encode($context, JSON_UNESCAPED_UNICODE) : '';
        $line = "[{$timestamp}] [{$level}] {$message}{$contextStr}\n";
        file_put_contents($this->logFile, $line, FILE_APPEND | LOCK_EX);
    }
}

配置与环境检测

php
<?php
declare(strict_types=1);

// 环境检测工具
class EnvironmentChecker
{
    public static function checkRequirements(array $requirements): array
    {
        $results = [];
        foreach ($requirements as $name => $check) {
            $results[$name] = is_callable($check) ? $check() : false;
        }
        return $results;
    }

    public static function getSystemInfo(): array
    {
        return [
            'php_version' => PHP_VERSION,
            'os' => PHP_OS,
            'sapi' => PHP_SAPI,
            'memory_limit' => ini_get('memory_limit'),
            'max_execution_time' => ini_get('max_execution_time'),
            'loaded_extensions' => get_loaded_extensions(),
        ];
    }
}

常见问题排查

问题可能原因解决方案
连接超时网络问题/配置错误检查配置,增加超时时间
权限不足文件/目录权限使用 chmod/chown 修正
性能下降索引缺失/数据量大添加索引,优化查询
数据不一致并发冲突/事务残留使用锁机制和事务
内存溢出大数据集/未释放资源增大内存限制,分批处理

故障排除步骤

  1. 检查错误日志和异常信息
  2. 确认配置和环境是否正确
  3. 使用调试工具逐步排查
  4. 参考官方文档查找已知问题

版本兼容性说明

功能最低版本说明
基础功能PHP 8.1本文档基准版本
只读属性PHP 8.1public readonly 修饰符
枚举类型PHP 8.1enum 类型和 match 表达式
FiberPHP 8.1协程/轻量级并发
命名参数PHP 8.0foo(arg_name: value)
联合类型PHP 8.0`int
Null 安全运算符PHP 8.0$obj?->method()
析构器 promotionPHP 8.0__construct(public $x)
php
<?php
declare(strict_types=1);

// 版本兼容性检测
function ensureVersion(string $minVersion): void
{
    if (version_compare(PHP_VERSION, $minVersion, '<')) {
        throw new RuntimeException(
            sprintf('需要 PHP %s+, 当前版本: %s', $minVersion, PHP_VERSION)
        );
    }
}

ensureVersion('8.1.0');

参考链接