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 状态码。
<?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 中组合多个条件。
<?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 与非身份比较场景一起使用。
<?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
此示例展示了使用数组和条件的进阶模式匹配。
<?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 如何返回函数调用或复杂表达式。
<?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 枚举一起使用,以进行类型安全的匹配。
<?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 语句进行对比。
<?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'。
最佳实践
- 详尽性: 始终包含一个默认情况,除非涵盖了所有可能性。
- 可读性: 保持 match arms 简单;将复杂逻辑移至函数。
- 类型安全: 利用 match 的严格比较来实现更可预测的代码。
- 返回值: 使用 match 的表达式特性直接赋值。
- 性能: 优先使用 match 而不是 switch 以获得更好的性能和安全性。
来源
本教程介绍了 PHP 的 match 表达式,并提供了实际示例,展示了它的语法、相对于 switch 的优势以及各种用例。
作者
列出 所有 PHP 教程。