第四章:PHP流程控制——让代码学会“思考”和“重复”
流程控制,说白了就是让代码能根据不同的情况做不同的事,或者反复做同一件事。这是编程的骨架,没有它,代码就是一潭死水。我个人习惯把流程控制分成两大类:分支判断和循环迭代。今天咱们就把它们彻底聊透。
4.1 if-else 判断:最基础的分支逻辑
if-else 是 PHP 里最常用的判断结构。它的逻辑很简单:如果条件成立,就执行 A;否则执行 B。
<?php
$score = 85;
if ($score >= 90) {
echo "优秀";
} elseif ($score >= 80) {
echo "良好";
} elseif ($score >= 60) {
echo "及格";
} else {
echo "不及格";
}
// 输出:良好
?>
这里有个小细节:elseif 可以连着写,但要注意条件的顺序。我建议把最严格的条件放在最前面,否则后面的分支可能永远执行不到。
elseif 写成 else if(中间有空格)。虽然 PHP 也支持,但为了代码风格统一,我建议始终使用 elseif。
4.2 switch 分支:多路选择的优雅写法
当你要判断的变量只有几个固定值时,switch 比 if-else 更清晰。你想想看,如果写一堆 elseif 去比较同一个变量,是不是很啰嗦?
<?php
$day = "Monday";
switch ($day) {
case "Monday":
echo "新的一周开始了";
break;
case "Friday":
echo "明天就周末了";
break;
case "Saturday":
case "Sunday":
echo "周末愉快";
break;
default:
echo "普通工作日";
}
?>
嗯,这里要注意 break。如果你忘了写 break,代码会继续往下执行下一个 case,这叫“穿透”。有时候我们故意利用穿透(比如上面的 Saturday 和 Sunday 共用一段代码),但更多时候它是 bug 的来源。
4.3 while 循环:先判断,后执行
while 循环的逻辑是:只要条件为真,就一直执行循环体。它适合那种“不知道要循环多少次”的场景。
<?php
$i = 1;
while ($i <= 5) {
echo "第 {$i} 次循环\n";
$i++;
}
// 输出 1 到 5
?>
这里有个经典陷阱:死循环。如果你忘了写 $i++,条件永远为真,程序就会卡死。我在刚学 PHP 时干过这事,浏览器直接崩溃了。
4.4 do-while 循环:先执行,后判断
do-while 和 while 的唯一区别:它至少会执行一次循环体。因为条件判断在循环体后面。
<?php
$i = 10;
do {
echo "至少执行一次";
$i++;
} while ($i <= 5);
// 输出:至少执行一次
?>
你看,即使条件不成立,它也执行了一次。这种结构在“先做一次,再决定要不要继续”的场景下很实用。比如用户输入验证,先提示一次,如果输入不对再继续提示。
4.5 for 循环:最经典的计数循环
for 循环适合明确知道循环次数的场景。它的语法稍微复杂一点,但用熟了会觉得非常顺手。
<?php
for ($i = 0; $i < 10; $i++) {
echo "当前值:{$i}\n";
}
?>
for 循环的三个部分:初始化、条件判断、步进更新。我个人习惯把循环变量命名为 $i、$j、$k,嵌套循环时依次递增。
count() 这类函数放在循环外面计算。否则每次循环都调用一次函数,性能会受影响。
4.6 foreach 循环:遍历数组的利器
foreach 是 PHP 里我最喜欢的循环结构。它专门用来遍历数组,不需要关心下标,也不需要手动控制循环变量。
<?php
$users = ["张三", "李四", "王五"];
foreach ($users as $name) {
echo "用户:{$name}\n";
}
// 带键名的遍历
$scores = ["张三" => 90, "李四" => 85];
foreach ($scores as $name => $score) {
echo "{$name} 的成绩是 {$score}\n";
}
?>
foreach 遍历的是数组的副本,也就是说你在循环里修改 $name 不会影响原数组。如果你想修改原数组,需要加 & 引用符号。
$name 仍然保留着对最后一个元素的引用。如果不小心再次使用 $name,可能会意外修改数组。我建议循环结束后立即 unset($name)。
4.7 break 与 continue:控制循环的“刹车”和“跳过”
这两个关键字用来精细控制循环的执行流程。
- break:立即终止整个循环,跳出循环体。
- continue:跳过当前这次循环的剩余代码,直接进入下一次循环。
<?php
// break 示例:找到第一个大于 50 的数就停止
$numbers = [10, 20, 55, 30, 70];
foreach ($numbers as $num) {
if ($num > 50) {
echo "找到:{$num}";
break; // 找到后立即停止
}
}
// continue 示例:跳过偶数
for ($i = 1; $i <= 10; $i++) {
if ($i % 2 == 0) {
continue; // 跳过偶数
}
echo "奇数:{$i}\n";
}
?>
break 还可以接受一个数字参数,表示跳出几层循环。比如 break 2 表示跳出两层嵌套循环。不过我个人不太推荐这么用,代码可读性会下降。如果嵌套太深,不如把内层循环抽成函数。
4.8 实战建议:如何选择合适的循环
| 场景 | 推荐循环 | 原因 |
|---|---|---|
| 遍历数组 | foreach | 最简洁,不需要手动管理下标 |
| 已知循环次数 | for | 语法清晰,初始化/条件/步进一目了然 |
| 未知循环次数,先判断 | while | 条件在循环体前面,逻辑直观 |
| 至少执行一次 | do-while | 先执行后判断,保证至少运行一次 |
| 多分支固定值判断 | switch | 比 if-else 更清晰,支持穿透 |
最后说一句:不要滥用循环。有时候用数组函数(如 array_map、array_filter)能写出更简洁的代码。但如果你刚开始学,先用循环把逻辑跑通,再考虑优化也不迟。
好了,流程控制这块就聊到这。下一章咱们会深入函数和命名空间,那才是真正开始搭建项目骨架的时候。