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