PHP 循环语句:for/while/do-while/foreach 及循环控制
PHP 循环概述
循环用于重复执行一段代码,是编程中最常用的结构之一。PHP 有四种循环语句。
一、for 循环
基本语法
<?php\nfor ($i = 0; $i < 5; $i++) {\n echo "第 {$i} 次循环\\n";\n}\n// 输出:第0次循环 第1次循环 ... 第4次循环\n?>
for 循环的三个表达式
<?php\n/*\nfor (表达式1; 表达式2; 表达式3)\n 表达式1:初始值,只执行一次\n 表达式2:条件判断,每次循环前判断\n 表达式3:每次循环结束后执行\n*/\n\n// 表达式可以省略(但分号要保留)\n$i = 0;\nfor (; $i < 5;) {\n echo $i++;\n}\n\n// 多个变量\nfor ($i = 0, $j = 0; $i < 5; $i++, $j += 2) {\n echo "i={$i} j={$j}\\n";\n}\n?>
死循环及退出
<?php\n// 死循环(小心使用)\nfor (;;) {\n echo "无限循环\\n";\n break; // 必须配合 break,否则真死循环\n}\n\n// 实际应用:处理队列\n$queue = ['task1', 'task2', 'task3'];\nfor ($i = 0; $i < count($queue);) {\n process($queue[$i++]);\n}\n?>
二、while 循环
基本语法
<?php\n$i = 0;\nwhile ($i < 5) {\n echo "循环 {$i}\\n";\n $i++;\n}\n?>
while 的实际用途
<?php\n// 读取文件行\n$fp = fopen('data.txt', 'r');\nwhile (!feof($fp)) {\n $line = fgets($fp);\n echo $line;\n}\nfclose($fp);\n\n// 遍历数组(配合 next/prev)\n$arr = ['a', 'b', 'c', 'd'];\nwhile (list($key, $val) = each($arr)) {\n echo "{$key} => {$val}\\n";\n}\n?>
三、do-while 循环
do-while 先执行循环体,再判断条件,至少执行一次:
<?php\n$i = 0;\ndo {\n echo "第 {$i} 次\\n";\n $i++;\n} while ($i < 5);\n\n// 典型应用:用户输入验证\ndo {\n $input = trim(fgets(STDIN));\n if (empty($input)) {\n echo "输入不能为空,请重新输入:";\n }\n} while (empty($input));\necho "您输入了:{$input}";\n?>
四、foreach 循环(最重要)
遍历数组
<?php\n$colors = ['红', '绿', '蓝'];\n\n// 遍历值\nforeach ($colors as $color) {\n echo $color . "\\n";\n}\n\n// 遍历键和值\nforeach ($colors as $index => $color) {\n echo "{$index}: {$color}\\n";\n}\n\n// 遍历关联数组\n$user = ['name' => '张三', 'age' => 25, 'city' => '绍兴'];\nforeach ($user as $key => $value) {\n echo "{$key} = {$value}\\n";\n}\n?>
遍历多维数组
<?php\n$students = [\n ['name' => '张三', 'score' => 92],\n ['name' => '李四', 'score' => 85],\n ['name' => '王五', 'score' => 78],\n];\n\nforeach ($students as $student) {\n echo "{$student['name']}: {$student['score']}分\\n";\n}\n\n// 如果需要修改数组元素的值,用引用\nforeach ($students as &$student) {\n $student['score'] += 10; // 每人加10分\n}\nunset($student); // 解除引用,防止后面误用\n?>
遍历对象
<?php\nclass User {\n public string $name = '张三';\n public int $age = 25;\n private string $email = 'zhang@example.com';\n}\n\n$user = new User();\nforeach ($user as $key => $value) {\n echo "{$key}: {$value}\\n";\n // 输出:name: 张三,age: 25(private 不输出)\n}\n?>
五、循环控制:break 和 continue
break:跳出循环
<?php\n// 找到第一个大于10的数\n$numbers = [3, 7, 12, 5, 19, 8];\nforeach ($numbers as $n) {\n if ($n > 10) {\n echo "找到了:{$n}";\n break; // 跳出整个循环\n }\n}\n\n// break 可指定层数(跳出多层循环)\nfor ($i = 0; $i < 3; $i++) {\n for ($j = 0; $j < 5; $j++) {\n if ($j == 2) {\n break 2; // 跳出两层循环\n }\n echo "i={$i} j={$j}\\n";\n }\n}\n?>
continue:跳过本次循环
<?php\n// 跳过所有奇数,只处理偶数\nfor ($i = 0; $i < 10; $i++) {\n if ($i % 2 === 1) {\n continue; // 跳过本次循环,进入下一次\n }\n echo $i . "\\n"; // 输出 0,2,4,6,8\n}\n\n// continue 也可指定层数\nfor ($i = 0; $i < 3; $i++) {\n for ($j = 0; $j < 3; $j++) {\n if ($j == 1) continue 2; // 跳过当前内层循环,进入外层下一次\n echo "i={$i} j={$j}\\n";\n }\n}\n?>
六、循环嵌套
<?php\n// 九九乘法表\nfor ($i = 1; $i <= 9; $i++) {\n for ($j = 1; $j <= $i; $j++) {\n echo "{$j}×{$i}=" . ($i * $j) . "\\t";\n }\n echo "\\n";\n}\n\n// 二维数组遍历\n$matrix = [\n [1, 2, 3],\n [4, 5, 6],\n [7, 8, 9],\n];\nforeach ($matrix as $row) {\n foreach ($row as $cell) {\n echo str_pad($cell, 4);\n }\n echo "\\n";\n}\n?>
七、替代语法(模板中使用)
<?php $items = ['苹果', '香蕉', '橙子']; ?>\n\n<ul>\n<?php foreach ($items as $item): ?>\n <li><?php echo $item; ?></li>\n<?php endforeach; ?>\n</ul>\n\n<?php for ($i = 0; $i < 5; $i++): ?>\n <p>第 <?php echo $i; ?> 段文字</p>\n<?php endfor; ?>
八、遍历时修改数组(引用遍历)
<?php\n$nums = [1, 2, 3, 4, 5];\n\n// 值传递:修改不影响原数组\nforeach ($nums as $n) {\n $n *= 2; // 不影响原数组\n}\nprint_r($nums); // [1,2,3,4,5]\n\n// 引用遍历:修改会影响原数组\nforeach ($nums as &$n) {\n $n *= 2;\n}\nunset($n); // 重要!解除引用\nprint_r($nums); // [2,4,6,8,10]\n\n// 过滤数组(保留符合条件的)\n$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nforeach ($items as $key => $val) {\n if ($val % 2 === 0) {\n unset($items[$key]); // 删除偶数\n }\n}\n$items = array_values($items); // 重建索引\nprint_r($items); // [1,3,5,7,9]\n?>
总结
- foreach 是遍历数组最常用的方式,支持键值对遍历
- while 适合条件驱动型循环(不知道循环次数)
- for 适合已知循环次数的场景
- do-while 先执行后判断,至少执行一次
- 遍历数组时用引用(
&$val)才能修改原数组 - 使用引用遍历后务必
unset($val)解除引用