PHP8 的两个令人兴奋的功能:JIT 和匹配表达式
PHP8 带来了两个最令人兴奋的功能:JIT 和匹配表达式。有很多关于 PHP8 JIT 的材料进行了讨论。我们在这里不再赘述。可以学习一下鸟哥的博客(风雪一角)。
在本文中,我们将讨论另一种新引入的语法,即匹配表达式语法,它是 PHP 8 中引入的最佳功能之一。它使用类似 switch 的语法。
基本功能
$status = match($request_method) {
'post' => $this->handlePost(),
'get', 'head' => $this->handleGet ( ),
default => throw new \Exception('Unsupported'),
};
使用 switch ... 大小写进行比较。实现上述功能,代码稍微复杂一点:
switch ($request_method) {
case 'post':
$status = $this->handlePost();
break
case 'get':
case 'head':
$status = $this->handleGet();
break;
default:
new \exception('不支持' );
};
与 switch 相比,match 直接返回值,不需要任何中间变量(如上例中的 $status)。
表达式可以返回一个值
在每个分支中它可以分配给一个变量。
$name = match(2) {
1 => '一',
2 => '二',
};
echo $name; // 《二》
不需要将返回值赋给其他变量,匹配语句返回值可以直接从匹配表达式中返回。
可以匹配多个条件
匹配表达式可以包含一个或多个匹配条件,其行为类似于块中的多个级联按键开关。
match($request_method) {
'post' => $this->handlePost(),
'get', 'head' => $this->handleGet(),
};
如果 $request_method === 'get' 和 $request_method === 'head' 两个条件 $this 就会被执行->handleGet()。
每个分支只能包含一个表达式
与可以包含任意数量表达式的 switch 块不同,一条 match 语句只能包含一个表达式。
match($name) {
'XXX' =>
init();
doth();
};
上面的语法是错误的。 =>只能有一个表达式。
隐式中断
匹配表达式每个匹配分支仅允许一个表达式,并且不需要像 switch 块那样的中断。
switch('测试'){
case'测试':
$this->doTest();
case'发送':
$this->sendmsg();
}
switch中的一个常见错误...Caser就是忘记了break语句,该语句将进程直接引导到下一个分支。在前述的切换块中,缺少停顿;语句阻止代码正常执行 $this->doTest()。
match ('test') {
'test' => $this->doTest(),
'send' => $this->sendmsg(),
};
匹配表达式无需显式的break语句即可工作。它只执行匹配分支并直接返回值。
默认分支
match 语句支持默认分支,其工作方式与 switch ... case 块中的 default case 类似。如果没有其他条件匹配,则执行默认匹配分支。
match ('DEF') {
'aaa' => ...,
'bbb' => ...,
default => echo '无匹配: ' 。 $name,
};
// "NO matchin: DEFF"
匹配表达式必须满足条件
如果 switch 与 case 键不匹配,它会默默地阻塞代码流。匹配表达式则不然。
匹配表达式中必须有与表达式匹配的条件或默认处理的条件。如果没有匹配并且未设置默认分支,则匹配表达式将引发 \UnhandledMatchError 异常。
$value = 3;
match($value) {
1 => '一',
2 => '二',
};
如果上面的代码是执行时,抛出错误:
Fatal error: Uncaught UnhandledMatchError in ...
match\UnhandledMatchError 如果表达式中没有匹配项,则表达式会抛出异常。
\UnhandledMatchError 是 PHP 8 中的一个新异常类,它扩展了 \Error。所有 PHP 核心异常类的完整层次结构。
该类可以轻松扩展:
class UnhandledMatchError extends \Error {}
非强制类型的严格匹配
匹配表达式中最重要的设计选择之一是它对非强制类型的支持强制匹配类型。
函数读取(混合$key):String {
返回匹配项($key){
1 => '总数1',
'1' => '字符串1',
true => 'Bool true',
[] => '空数组',
[1] => '数组 [1]',
};
}
read( 1)); //“整数1”
read('1'); // "String 1"
在典型的switch块中,它的大小写是松散匹配的,即使用==。在匹配表达式中,所有匹配分支都被严格比较(===)。
在上面的代码片段中,每个分支都与其值和类型相匹配。
匹配任何表达式
匹配表达式允许给定值与表达式匹配。
match($httpst){
404 => '找不到页面',
响应::REDIRECT => '重定向',
$client->getCode() => '客户端错误',
$response->getCode() => '响应错误',
default => '未知错误'
};
表达式按其列出的顺序进行计算。
匹配表达式尝试按以下顺序匹配 $httpst:
1。 $httpst === 404
2。 $httpst === 响应::重定向
3。 $httpst == = $client->getCode()
4. $httpst === $response->getCode()
5.默认
如果找到正匹配,则不尝试其他分支,立即返回。
匹配 VS 开关
向后兼容性影响
匹配表达式是 PHP 8 中的新语法。具有匹配表达式的代码在旧版 PHP 中不起作用。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。