ZetCode

PHP match 表达式

最后修改于 2025 年 4 月 16 日

PHP match 表达式是 PHP 8 中引入的一个强大特性。它提供了比 switch 语句更简洁、更安全的替代方案。 Match 严格比较值 (===) 并返回值,使其更可预测。

基本定义

match 表达式将一个主体值与多个备选项进行比较。它返回第一个匹配 case 的值。与 switch 不同,它执行严格的类型比较,并且不需要 break 语句。

语法:match (subject) { pattern1 => result, pattern2 => result }。 match 必须是详尽的或包含一个默认情况。它计算为一个可以赋值给变量的值。

与 switch 的主要区别:严格比较,返回值,没有 fall-through,以及更紧凑的语法。 Match 是一个表达式,而不是像 switch 那样的语句。

基本 match 示例

此示例演示了一个简单的 match 表达式,用于检查 HTTP 状态码。

basic_match.php
<?php

declare(strict_types=1);

$statusCode = 404;

$message = match($statusCode) {
    200 => 'OK',
    301 => 'Moved Permanently',
    404 => 'Not Found',
    500 => 'Internal Server Error',
    default => 'Unknown Status Code'
};

echo $message; // Outputs: Not Found

代码将状态码与几个可能的值进行匹配。 每个 case 指定一个模式和相应的结果。 默认情况处理任何未匹配的值。 结果被分配给 $message。

使用多个条件的 match

此示例展示了如何在单个 match arm 中组合多个条件。

multiple_conditions.php
<?php

declare(strict_types=1);

$age = 25;

$category = match(true) {
    $age < 13 => 'Child',
    $age >= 13 && $age < 20 => 'Teenager',
    $age >= 20 && $age < 65 => 'Adult',
    default => 'Senior'
};

echo $category; // Outputs: Adult

match 使用 true 作为主体来评估布尔条件。 每个 arm 包含一个返回 true 或 false 的条件。 第一个为真的条件决定结果。 这种模式对于范围检查很有用。

使用非身份检查的 match

此示例演示了将 match 与非身份比较场景一起使用。

non_identity.php
<?php

declare(strict_types=1);

$input = '42';

$result = match((int)$input) {
    0 => 'Zero',
    42 => 'The Answer',
    1, 2, 3 => 'Small number',
    default => 'Other number'
};

echo $result; // Outputs: The Answer

输入在匹配之前被转换为整数。 多个值可以用逗号组合在一个 arm 中。 在类型转换后,match 执行严格的比较。 这展示了如何处理类型转换案例。

使用复杂模式的 match

此示例展示了使用数组和条件的进阶模式匹配。

complex_patterns.php
<?php

declare(strict_types=1);

$user = [
    'name' => 'Alice',
    'age' => 30,
    'status' => 'active'
];

$access = match(true) {
    !isset($user['name']) => 'Invalid user',
    $user['status'] === 'banned' => 'Access denied',
    $user['age'] < 18 => 'Parental control required',
    $user['status'] === 'active' => 'Full access',
    default => 'Limited access'
};

echo $access; // Outputs: Full access

match 对数组数据评估复杂条件。 每个 arm 检查用户数据的不同方面。 条件可以包括函数调用和嵌套检查。 这展示了 match 在复杂逻辑方面的灵活性。

match 返回函数

此示例展示了 match 如何返回函数调用或复杂表达式。

return_functions.php
<?php

declare(strict_types=1);

function getDiscount(string $memberType): float {
    return match($memberType) {
        'gold' => 0.2,
        'silver' => 0.1,
        'bronze' => 0.05,
        default => 0.0
    };
}

$discount = getDiscount('gold');
echo "Discount: " . ($discount * 100) . "%"; // Outputs: Discount: 20%

match 在函数中使用以返回不同的折扣值。 每个 arm 返回一个特定的浮点值。 该函数封装了匹配逻辑。 这种模式对于查找表和配置很有用。

使用枚举的 match

此示例演示了将 match 与 PHP 8.1 枚举一起使用,以进行类型安全的匹配。

enum_match.php
<?php

declare(strict_types=1);

enum UserRole: string {
    case ADMIN = 'admin';
    case EDITOR = 'editor';
    case READER = 'reader';
}

$role = UserRole::EDITOR;

$permissions = match($role) {
    UserRole::ADMIN => ['create', 'read', 'update', 'delete'],
    UserRole::EDITOR => ['create', 'read', 'update'],
    UserRole::READER => ['read']
};

print_r($permissions); // Outputs Array([0]=>create [1]=>read [2]=>update)

match 与 enum case 无缝协作。 每个 enum 值映射到特定的权限。 编译器确保处理所有 enum case。 这提供了 switch 语句所缺乏的类型安全。

match vs switch 比较

此示例将 match 与传统的 switch 语句进行对比。

match_vs_switch.php
<?php

declare(strict_types=1);

$value = '1';

// Switch example (loose comparison)
switch ($value) {
    case 1:
        $result = 'Integer 1';
        break;
    case '1':
        $result = 'String "1"';
        break;
    default:
        $result = 'Other';
}

echo "Switch: $result\n"; // Outputs: Switch: Integer 1

// Match example (strict comparison)
$result = match($value) {
    1 => 'Integer 1',
    '1' => 'String "1"',
    default => 'Other'
};

echo "Match: $result"; // Outputs: Match: String "1"

switch 使用松散比较 (==),而 match 使用严格比较 (===)。 Switch 需要 break 语句以防止 fall-through。 Match 直接返回值。 该示例展示了它们如何不同地处理字符串 '1'。

最佳实践

来源

PHP match 文档

本教程介绍了 PHP 的 match 表达式,并提供了实际示例,展示了它的语法、相对于 switch 的优势以及各种用例。

作者

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

列出 所有 PHP 教程