for 循环
for 循环是 PHP 中最常用的循环结构之一,它将初始化、条件判断和递增操作整合在一个语句中。for 循环特别适合迭代次数已知的场景,如遍历数字序列、固定长度的数组等。
基础概念
for 循环由三个部分组成:
- 初始化(Initialization):在循环开始前执行一次,通常用于设置计数器变量。
- 条件(Condition):在每次迭代开始前判断,为
true则执行循环体,为false则退出。 - 递增(Increment):在每次循环体执行完毕后执行,通常用于更新计数器。
执行顺序
for 循环的执行顺序:初始化 -> 条件判断 -> 循环体 -> 递增 -> 条件判断 -> 循环体 -> 递增 -> ... 直到条件为 false。
语法结构
基本 for 语法
<?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 = 5for 循环的三个表达式都可以省略
<?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
declare(strict_types=1);
echo "<ul>\n";
for ($i = 1; $i <= 5; $i++):
echo "<li>第 {$i} 项</li>\n";
endfor;
echo "</ul>\n";详细说明
多重初始化和递增
for 循环的初始化和递增部分可以用逗号分隔多个表达式。
<?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
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
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
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
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
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
declare(strict_types=1);
function generateTimesTable(int $size = 10): string
{
$html = "<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\">\n";
$html .= " <tr>\n <th>×</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
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 | 至少执行一次 | 先执行后判断 |
注意事项
count() 放在条件中的性能问题:在
for循环条件中直接使用count($array)不会导致性能问题,因为 PHP 会在每次迭代中重新计算。但为了代码清晰,可以先将结果缓存到变量中。修改循环变量:在循环体内修改
$i可能导致意外的行为,建议保持循环变量的递增/递减逻辑简单明确。浮点数作为循环变量:浮点数精度问题可能导致循环次数不符合预期,建议使用整数循环变量。
无限循环:省略条件或条件永远为
true时,for循环也会变成无限循环,需配合break使用。
最佳实践
使用有意义的变量名:除了简单的
$i、$j,在复杂循环中使用描述性的变量名(如$rowIndex、$columnIndex)。避免在循环体中修改数组长度:在
for循环中遍历数组时,如果循环体内增删元素,可能导致跳过或重复处理。优先使用
foreach遍历数组:当不需要索引或需要遍历关联数组时,foreach是更好的选择。控制嵌套层级:超过两层嵌套的
for循环通常意味着需要重构,考虑提取函数或使用其他数据结构。限制循环次数:对于可能产生大量迭代的循环,设置合理的上限以避免性能问题。
下一节
数组遍历最常用的方式是 foreach 循环。接下来学习 foreach 循环。
进阶用法
调试与测试技巧
<?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
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
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 修正 |
| 性能下降 | 索引缺失/数据量大 | 添加索引,优化查询 |
| 数据不一致 | 并发冲突/事务残留 | 使用锁机制和事务 |
| 内存溢出 | 大数据集/未释放资源 | 增大内存限制,分批处理 |
故障排除步骤
- 检查错误日志和异常信息
- 确认配置和环境是否正确
- 使用调试工具逐步排查
- 参考官方文档查找已知问题
版本兼容性说明
| 功能 | 最低版本 | 说明 |
|---|---|---|
| 基础功能 | PHP 8.1 | 本文档基准版本 |
| 只读属性 | PHP 8.1 | public readonly 修饰符 |
| 枚举类型 | PHP 8.1 | enum 类型和 match 表达式 |
| Fiber | PHP 8.1 | 协程/轻量级并发 |
| 命名参数 | PHP 8.0 | foo(arg_name: value) |
| 联合类型 | PHP 8.0 | `int |
| Null 安全运算符 | PHP 8.0 | $obj?->method() |
| 析构器 promotion | PHP 8.0 | __construct(public $x) |
<?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');