match 比 switch 更安全,因强制严格比较、无穿透、自动终止、未匹配时抛出 UnhandledMatchError,并支持多值匹配、条件判断和异常抛出。

match 用 === 比 switch 的 == 更安全
switch 默认做松散比较,"200" 和 200 会被当成相等,一不留神就触发错误分支。比如用户传来的字符串 "200",在 case 200: 下直接命中,可能误删数据库或跳过权限校验。
match 强制使用严格比较(===),类型和值必须完全一致。这意味着:
-
"200"不会匹配200 -
0不会匹配false或空字符串 - 你得显式写出
"200" => ...或200 => ...,意图清晰
match 是表达式,天然避免 break 错误和穿透
switch 里漏写 break 就会“穿透”,下一个 case 也被执行——这种 bug 很难被测试覆盖,线上才暴露。
match 没有 break,每个分支自动终止,且它本身是表达式,直接返回值:
立即学习“PHP免费学习笔记(深入)”;
-
$message = match($code) { 200 => 'OK', 404 => 'Not Found' };—— 一行赋值完成 - 没有遗漏处理的分支时,
match抛出UnhandledMatchError,而不是静默走 default 或穿透 - 不写
default且无匹配项?立刻报错,不让你侥幸上线
多个值、表达式、异常抛出都支持单行声明
switch 要写一堆重复的 case,而 match 允许紧凑表达常见模式:
- 多值匹配:
200, 201, 204 => true - 条件判断:
match (true) { $score >= 90 => 'A', $score >= 70 => 'B' } - 运行时抛异常:
default => throw new InvalidArgumentException('Invalid') - 用
_替代default(语义更轻量,但功能等价)
这些不是语法糖,是把原本要拆成函数+if/switch 的逻辑,压进一个可读、可测、不可绕过的表达式里。
不写 default 时的 UnhandledMatchError 容易被忽略
很多人迁移到 match 后第一反应是删掉 default 分支,觉得“反正我穷举了所有情况”。但 PHP 不做静态分析,运行时万一来了个没列的值(比如新增 HTTP 状态码 422,但你只写了 200, 404, 500),就会炸出 UnhandledMatchError。
这不是缺陷,是设计:它逼你直面“未覆盖场景”。真要兜底,就老老实实写 default;真想让异常暴露问题,就别写——但得确保监控能捕获它。这点比 switch 静默 fallback 到空/default 更苛刻,也更可靠。



















