PHP switch 默认穿透,必须显式用 break/return/throw 终止;空 case 可省略 break,但含可执行语句时必须中断;推荐统一加 break 或改用 PHP 8+ 的 match 表达式杜绝穿透风险。
PHP 中
语句默认穿透,不写
就会继续执行下一个
,这不是语法错误,但极大概率是逻辑 Bug。
每个非空 case 必须显式终止流程
PHP 不会自动在
结束时跳出,它只看有没有
、
、
或函数自然结束。空
(比如只注释或什么都没写)可以不加
,但只要里面有一行可执行语句,就必须主动中断。
推荐统一用
,除非你明确需要穿透且已加注释
函数内可用
替代
,更彻底,也避免漏写
不要依赖
位置来“兜底”——如果它不在最后,后面没
同样会穿透
真要穿透时必须加 // fall through 注释
多个
共享同一段逻辑(比如
都输出 30 天),这是合理穿透,但必须让后续维护者一眼看懂意图。
注释必须紧贴
下一行或同一行末尾,如:
PHPStan、Psalm 等静态分析工具能识别这个注释,忽略该处警告;没注释则报错
CI 流程中加入
可提前拦截无注释的穿透
PHP 8+ 优先用
表达式替代
是 PHP 8 引入的严格版分支语法,从设计上就杜绝了穿透问题:它不接受
,也不允许隐式穿透,每个分支必须有返回值,未匹配会抛
。
纯CSS制作Switch动画开关按钮
纯CSS制作Switch动画开关按钮
下载
简单值匹配场景直接替换:
不能写
这类无返回语句,强制你把逻辑收束为表达式
类型更安全,默认严格比较,不会把字符串
当成整数
匹配
松散比较 + 穿透 = 隐形雪崩
PHP
默认用
比较,这意味着
会意外匹配
、
、
,如果再没
,这些本不该进来的值就会一路穿透执行后续所有分支。
关键业务中,改用
的唯一可靠方式是换
,或手动转类型:
永远不要在
值里写函数调用或表达式,如
是语法错误
不是可选项——漏掉它,不匹配的输入就静默跳过,连日志都没有
穿透本身不是缺陷,是语言特性;但人脑记不住哪些地方该穿透、哪些不该,所以最稳妥的做法是:默认都加
,真要穿透就加注释,新项目直接用
。
switchbreakcasecasebreakreturnthrowcasebreakbreakreturnbreakdefaultbreakcasecase '4': case '6': case '9': case '11':casecase '4': // fall throughphpstan analyse --level=5matchswitchmatchbreakUnhandledMatchErrormatch ($status) { 200 => 'OK', 404 => 'Not Found' };echo"1"1switch==case 0:false''nullbreak===matchcase (int)$input:casecase $x > 10:defaultbreakmatch