订单状态判断写了一长串 if else,看着乱,换 php switch 结构清晰些。但 switch 有个 if 没有的特性,漏了 break 整段逻辑就跑飞了。

基本写法

switch ($status) { case 1: echo '待付款'; break; case 2: echo '已发货'; break; default: echo '其他'; }

程序从上往下找匹配的 case,命中后执行里面的语句,遇到 break 跳出。所有 case 都不中就走 default,default 写在最后但不是必须的。case 后面跟的是常量表达式,变量和函数调用放在那里,PHP 8 之前的版本会直接报错,这点和某些语言不一样。

break漏掉会怎样

case 命中后如果没有 break,代码会继续执行下一个 case 的语句,这叫穿透,方向是往下不往上,命中位置之后的所有分支都会执行。用得好可以合并相同逻辑,比如三个状态都打印同一段提示,把 case 写在一起不加 break;忘了写就是事故,明明匹配的是状态 1,状态 2 的发货通知也跟着发出去了。写的时候每个 case 先补上 break,确认需要合并再删。

比较方式有个坑

PHP 8 之前的版本,case 匹配是松散比较,字符串和数字比较时会先转换类型,0 和任意非数字字符串相等这种著名案例就是出在这里,某些奇怪输入可能命中意外的分支。PHP 8 收紧了规则,数字和字符串比较时会先把数字转成字符串再比,行为更符合直觉。老项目升级时这块值得重点过一遍。

还有个冷知识:在 switch 里写 continue,PHP 会把它当 break 用,同时给一条警告,想跳过本次循环得重新组织代码结构。

PHP 8 还提供了 match 表达式,写法和 php switch 最像,但它是严格比较、不会穿透,每个分支自带返回值,一行就能搞定状态映射。新项目里简单的值映射优先用 match,分支多、每个分支逻辑重的再用 switch,状态值特别多的时候,把映射提成数组配置反而更好维护。