PHP 控制流程
程序的三大基本结构是顺序、分支、循环。这一章讲 PHP 的分支(if / switch / match)和循环(while / for / foreach)。PHP 的控制结构和 C/Java 几乎一样,但 foreach 是真正的明星——它是处理 PHP 数组的标配。
1. if 条件语句
if 是最基础的条件判断。PHP 还支持 elseif 链和 else 兜底:
<?php
$score = 78;
// if / elseif / else
if ($score >= 90) {
echo "优秀";
} elseif ($score >= 80) {
echo "良好";
} elseif ($score >= 60) {
echo "及格";
} else {
echo "不及格";
}
// 单行 if 也要加大括号(PSR-12 强制)
if ($ok) {
doSomething();
}
// 替代语法(常见于模板)
if ($user):
echo "已登录";
else:
echo "未登录";
endif;几个要点:
- elseif 必须连写(不是
else if,虽然后者在带花括号时也能工作,但 PSR-12 推荐elseif)。 - 单行语句也要加大括号(PSR-12 强制),不要省略。
- 替代语法(
if (): ... endif;)用于模板里和 HTML 混排时,比花括号更清晰。
2. switch 与 match
当一个变量需要对多个具体值做不同处理时,用 switch 比 if-elseif 链清晰:
<?php
$day = "Mon";
switch ($day) {
case "Mon":
case "Tue": // 多个 case 共享一段代码(贯穿)
case "Wed":
echo "工作日";
break; // 不 break 会继续往下执行!
case "Sat":
case "Sun":
echo "周末";
break;
default: // 默认分支
echo "未知";
}
// ⚠️ switch 是弱比较(==)
switch ("0") {
case 0: echo "数字零"; break; // 会匹配!
}
// 用 match(PHP 8+)替代,严格比较
$result = match($day) {
"Mon", "Tue", "Wed" => "工作日",
"Sat", "Sun" => "周末",
default => "未知",
};两个坑:
- 别忘了 break——漏掉 break 会贯穿(fall-through)到下一个 case,这是 switch 最经典的 bug。偶尔会故意贯穿共享代码(见 Mon/Tue/Wed)。
- switch 用弱比较(
==),"0"会匹配case 0。PHP 8 加入的match表达式是严格比较,推荐替代 switch。
match 是 PHP 8 的新东西:返回值(不是语句)、严格比较、必须穷举(没匹配会抛异常)、多个值用逗号分组。凡是 switch 能写的,match 都能写得更好,PHP 8+ 项目推荐优先用 match。
3. while 与 do-while
while 用于不确定次数的循环(如读文件、消费队列):
<?php
// while:先判断后执行
$i = 0;
while ($i < 5) {
echo $i;
$i++;
}
// 输出: 01234
// do-while:先执行后判断(至少执行一次)
$j = 0;
do {
echo $j;
$j++;
} while ($j < 0);
// 输出: 0(条件为 false,但已执行一次)区别:while 先判断后执行(可能一次都不执行);do-while 先执行后判断(至少执行一次)。Web 开发中 while 比 for 少,但读数据库结果集时常用。
4. for 循环
for 用于已知次数的循环,经典三段式(初始化;条件;步进):
<?php
// for 循环:经典三段式
for ($i = 0; $i < 5; $i++) {
echo "第 {$i} 次\n";
}
// 倒序
for ($i = 10; $i > 0; $i--) {
echo $i;
}
// 多变量
for ($i = 0, $j = 10; $i < $j; $i++, $j--) {
echo "$i - $j\n";
}
// 无限循环(谨慎)
for (;;) {
if (someCondition()) break;
}5. foreach — PHP 数组的标配
foreach 是 PHP 处理数组最重要的循环。它有两种形式:只取值,或同时取键和值:
<?php
$fruits = ["苹果", "香蕉", "橙子"];
// 形式 1:只取值
foreach ($fruits as $f) {
echo $f;
}
// 形式 2:同时取键和值
foreach ($fruits as $index => $f) {
echo "[{$index}] {$f}";
}
// 遍历关联数组
$user = ["name" => "小明", "age" => 25];
foreach ($user as $key => $value) {
echo "{$key}: {$value}\n";
}
// name: 小明
// age: 25
// ⚠️ 默认不修改原数组,要修改加 &
foreach ($fruits as &$f) {
$f = "新" . $f;
}
unset($f); // 用完断开引用,避免后续 bug几个要点:
- 关联数组必须用 foreach(不能用 for,因为键不是数字)。
- 默认 foreach 是拷贝遍历,修改
$f不影响原数组。 - 要修改原数组加
&(引用),语法详见上方 cForeach 代码块。 - 用完引用 记得 unset,否则后续误用同一变量名会改到原数组的最后一个元素——这是著名陷阱。
6. break 与 continue
这两个用于提前跳出或跳过本次:
<?php
// break:跳出循环(可指定层数)
for ($i = 0; $i < 3; $i++) {
for ($j = 0; $j < 3; $j++) {
if ($j === 2) break 2; // 跳出 2 层循环
echo "$i-$j ";
}
}
// continue:跳过本次,进入下次
for ($i = 0; $i < 5; $i++) {
if ($i % 2 === 0) continue;
echo $i; // 1 3
}
// 在 switch 里 break 只跳出 switch
// 在循环里的 switch 想跳出整个循环,用 break 2PHP 特色:break N 和 continue N 可以指定跳几层循环,在嵌套循环里很有用,但滥用会降低可读性。
7. 控制结构的替代语法(模板专用)
当 PHP 与 HTML 混排时,用冒号语法比花括号清晰得多。WordPress、Laravel Blade 的视图里到处都是:
if (...): ... elseif (...): ... else: ... endif;foreach ($arr as $v): ... endforeach;for (...): ... endfor;while (...): ... endwhile;
这样做的好处:HTML 结束标签 </div> 和 PHP 右花括号长得太像,容易不配对;冒号语法 endforeach; 一眼就能看出对应关系。
8. PHP 8.1+ 的 enum 枚举(扩展)
对"一组固定的值"做分支,PHP 8.1 引入 enum 比常量或字符串更安全。配合 match 表达式非常优雅,大型项目建议用 enum 替代裸字符串:
- 状态机:用 enum 定义一组状态(如 Pending / Active / Closed)。
- 类型安全:编译期就能发现拼写错误。
- 配合 match 强制穷举,新加成员时所有 match 都会被检查到。
小结
这一章你掌握了 PHP 的分支(if / elseif / switch / match)和循环(while / do-while / for / foreach),以及 break/continue 和模板用的替代语法。下一篇函数——把重复代码封装起来。
← 上一篇 PHP 运算符
下一篇 PHP 函数 →