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 教程。