PHP switch/case 语句
最后修改于 2025 年 4 月 16 日
PHP 的 switch 语句是复杂 if/elseif 链的替代方案。 它将一个值与多个 case 进行比较,并执行匹配的代码。 当针对许多可能的值测试单个变量时,switch 语句可以提高可读性。
基本定义
switch 语句计算一次表达式,并将其与多个 case 值进行比较。 当找到匹配项时,相应的代码块将执行,直到遇到 break 语句。
case 关键字定义了可能的匹配值。 break 语句退出 switch 块。 如果没有 break,则会继续执行下一个 case。
当没有找到匹配项时,会运行 default case。 建议使用它来处理意外值,但它是可选的。 switch 语句默认使用宽松比较 (==)。
基本 switch 语句
此示例演示了一个简单的 switch 语句,用于检查日期编号。
<?php
declare(strict_types=1);
$day = 3;
switch ($day) {
case 1:
echo "Monday";
break;
case 2:
echo "Tuesday";
break;
case 3:
echo "Wednesday";
break;
default:
echo "Invalid day";
}
该代码将 $day 变量与 case 值 1-3 进行比较。 当匹配到 3 时,打印 "Wednesday"。 break 语句防止了流程继续执行到其他 case。 Default case 处理 1-3 范围之外的值。
具有相同代码的多个 Case
此示例展示了如何将共享相同代码块的多个 case 分组。
<?php
declare(strict_types=1);
$month = "Feb";
switch ($month) {
case "Jan":
case "Feb":
case "Mar":
echo "First Quarter";
break;
case "Apr":
case "May":
case "Jun":
echo "Second Quarter";
break;
default:
echo "Other Quarter";
}
该代码按季度对月份进行分组。 没有 break 语句的 case 会继续执行下一个 case。 这允许多个值执行相同的代码块。 在此示例中,switch 比较字符串值。
使用 break 和 fall-through
此示例演示了 switch 语句中故意的 fall-through 行为。
<?php
declare(strict_types=1);
$score = 85;
switch (true) {
case $score >= 90:
echo "A";
break;
case $score >= 80:
echo "B";
// No break - intentional fall-through
case $score >= 70:
echo " (passing grade)";
break;
default:
echo "F (failing)";
}
该代码展示了一个带有部分 fall-through 的分数评估。 得分为 85 会打印 "B (passing grade)",因为执行会继续到下一个 case。 这种技术可以构建复杂的输出,但需要仔细的文档记录。
带枚举类型的 Switch
此示例演示了使用 PHP 8.1+ 枚举的 switch,以进行类型安全的比较。
<?php
declare(strict_types=1);
enum Status: string {
case PENDING = 'pending';
case APPROVED = 'approved';
case REJECTED = 'rejected';
}
$status = Status::APPROVED;
switch ($status) {
case Status::PENDING:
echo "Your request is pending review.";
break;
case Status::APPROVED:
echo "Your request was approved!";
break;
case Status::REJECTED:
echo "Your request was denied.";
break;
}
该代码使用类型化的枚举来表示状态值。 Switch case 直接与枚举 case 进行比较。 这提供了类型安全性并防止了无效的比较。 枚举使 switch 语句更加健壮且易于维护。
Switch vs If-Else 性能
此示例比较了 switch 和 if-else 在大型值集上的性能。
<?php
declare(strict_types=1);
$value = 500;
// Switch version
$start = microtime(true);
switch ($value) {
case 1: /* ... */ break;
// ... 500 cases ...
case 500: $result = "Found 500"; break;
}
$switchTime = microtime(true) - $start;
// If-else version
$start = microtime(true);
if ($value == 1) { /* ... */ }
// ... 500 elseif ...
elseif ($value == 500) { $result = "Found 500"; }
$ifTime = microtime(true) - $start;
echo "Switch: " . $switchTime . "s\n";
echo "If-else: " . $ifTime . "s\n";
该代码测试了在大型条件集中查找值 500 的执行时间。 对于许多条件,switch 语句通常优于 if-else 链。 PHP 优化了 switch,以使用跳转表用于整数 case。 对于少数条件,差异可以忽略不计。
带返回值的 Switch
此示例展示了在函数中使用 switch 来返回不同的值。
<?php
declare(strict_types=1);
function getDiscount(string $memberType): float {
switch ($memberType) {
case 'gold':
return 0.25;
case 'silver':
return 0.15;
case 'bronze':
return 0.10;
default:
return 0.05;
}
}
echo "Gold member discount: " . (getDiscount('gold') * 100) . "%";
该函数使用 switch 来确定折扣率。 每个 case 立即返回一个值,这使得 break 语句变得不必要。 这种模式对于值查找函数来说很简洁。 default case 提供了基本折扣率。
带数组的高级 Switch
此示例演示了使用数组值和复杂条件的 switch。
<?php
declare(strict_types=1);
$user = [
'role' => 'editor',
'status' => 'active',
'posts' => 42
];
switch (true) {
case $user['role'] === 'admin':
$access = 'full';
break;
case $user['role'] === 'editor' && $user['status'] === 'active':
$access = 'limited';
break;
case $user['posts'] > 50:
$access = 'extended';
break;
default:
$access = 'basic';
}
echo "Access level: $access";
该代码使用 switch(true) 来计算 case 中的复杂条件。 每个 case 都可以使用各种运算符检查不同的数组元素。 这种方法提供了类似 if-else 的灵活性,同时保持 switch 结构。 条件从上到下进行计算,直到找到匹配项。
最佳实践
- 始终使用 break,除非有意需要 fall-through
- 包含 default case 以处理意外值
- 按逻辑顺序排列 case(数字/字母或最频繁的优先)
- 保持 case 简单 - 将复杂的逻辑移动到函数
- 考虑 match() 用于 PHP 8.0+ 简单值返回
来源
本教程介绍了 PHP switch 语句,并附带了实用示例,展示了基本用法、fall-through、枚举、性能和高级技术。
作者
列出 所有 PHP 教程。