ZetCode

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 语句,用于检查日期编号。

basic_switch.php
<?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 分组。

multiple_cases.php
<?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 行为。

fallthrough.php
<?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,以进行类型安全的比较。

enum_switch.php
<?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 在大型值集上的性能。

performance.php
<?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 来返回不同的值。

return_switch.php
<?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。

array_switch.php
<?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 结构。 条件从上到下进行计算,直到找到匹配项。

最佳实践

来源

PHP switch 文档

本教程介绍了 PHP switch 语句,并附带了实用示例,展示了基本用法、fall-through、枚举、性能和高级技术。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我撰写了超过 1,400 篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出 所有 PHP 教程