PHP8 新出的一个语法很好用,就是 match 语句。match 语句跟原来的 switch 类似,不过比 switch 更加的严格和方便
基本功能
$status = match($request_method) { | |
'post' => $this->handlePost(), | |
'get', 'head' => $this->handleGet(), | |
default => throw new \Exception('Unsupported'), | |
}; |
用switch…case做对比,要实现上面的功能,代码要略繁琐一点:
switch ($request_method) { | |
case 'post': | |
$status = $this->handlePost(); | |
break; | |
case 'get': | |
case 'head': | |
$status = $this->handleGet(); | |
break; | |
default: | |
throw new \Exception('Unsupported'); | |
}; |
相比switch, match会直接返回值,无需中间变量(比如上例中的$status)。
当然,有的同学会说,谁会这么写,用个数组转换不行么?拜托,这是举例啊,数组也只能数字键和整数啊,万一key是需要其他表达式呢,万一你要多个key对应一个值呢,对吧?
那么如果使用match关键字呢,可以变成类似:
$result = match($input) { | |
"true" => 1, | |
"false" => 0, | |
"null" => NULL, | |
}; |
相比switch, match会直接返回值,可以直接赋值给$result了。
并且,类似switch的多个case一个block一样,match的多个条件也可以写在一起,比如:
$result = match($input) { | |
"true", "on" => 1, | |
"false", "off" => 0, | |
"null", "empty", "NaN" => NULL, | |
}; |
需要注意的和switch不太一样的是,以前我们用switch可能会经常遇到这种诡异的问题:
$input = "2 person"; | |
switch ($input) { | |
case 2: | |
echo "bad"; | |
break; | |
} |
你会发现,bad竟然被输出了,这是因为switch使用了宽松比较(==)。match就不会有这个问题了, 它使用的是严格比较(===),就是值和类型都要完全相等。
还有就是,当input并不能被match中的所有条件满足的时候,match会抛出一个UnhandledMatchError exception:
$input = "false"; | |
$result = match($input) { | |
"true" => 1, | |
}; |
会得到:
Fatal error: Uncaught UnhandledMatchError: Unhandled match value of type string
这样就不用担心万一match条件没写全导致了不可预知的错误。
另外还是要说明,match是关键字,也就是从PHP8开始它不能出现在namespace或者类名中,如果你的项目中有用match作为类名的:
class Match {}
在PHP8开始将会得到语法错误了, 当然,方法名中还是可以用的。
match VS switch
向后兼容性影响
match表达式是PHP 8中的新语法。使用match表达式的代码在较旧的PHP版本中将不起作用。
拿起你发财的小手点个赞再走吧