当前位置: 首页 > 科技观察

PHP8.0的新功能:匹配表情

时间:2023-03-19 11:59:58 科技观察

于上月底由PHP社区发布,这是PHP8的首发,正式版也将在今年年底发布。PHP8带来了两个最令人兴奋的特性:JIT和匹配表达式。在本文中,我们将讨论另一种新引入的语法,匹配表达式语法,可以说是PHP8中引入的最佳特性之一,它使用类似开关的语法。基本函数$status=match($request_method){'post'=>$this->handlePost(),'get','head'=>$this->handleGet(),default=>thrownew\Exception('Unsupported'),};使用switch...case进行比较。实现以上功能,代码稍微复杂一点:switch($request_method){case'post':$status=$this->handlePost();break;case'get':case'head':$status=$this->handleGet();break;default:thrownew\Exception('Unsupported');};与switch相比,match会直接返回值,不需要中间变量(如上例中的$status)。返回值的表达式可以分配给每个分支中的变量。$name=match(2){1=>'一',2=>'二',};不再需要将返回值赋值给其他变量,匹配语句的返回值可以直接从匹配表达式中返回。可以匹配多个条件匹配表达式可以包含一个或多个匹配条件,其行为类似于块中的多个级联大小写键开关。match($request_method){'post'=>$this->handlePost(),'get','head'=>$this->handleGet(),};满足$request_method==='get'和$request_method==='head'两个条件都会执行$this->handleGet()。每个分支只能包含一个表达式与可以包含任意数量的表达式的switch块不同,匹配语句只能包含一个表达式。匹配($name){'XXX'=>init();doth();};上面的语法是错误的。=>只能有一个表达式。隐式breakmatch表达式只允许每个匹配分支有一个表达式,并且不需要像switch块那样的break。switch('test'){case'test':$this->doTest();case'send':$this->sendmsg();}switch...caser中最容易犯的错误是忘记了break语句,这会导致流程直接转到下一个分支。在上面的switch块中,缺少一个break;语句会使代码$this->doTest()无法正常执行。match('test'){'test'=>$this->doTest(),'send'=>$this->sendmsg(),};match表达式在没有显式break语句的情况下工作。它只是执行一个匹配分支并立即返回值。defaultcasematch语句支持defaultcase,其工作方式类似于switch...case块中的defaultcase。如果没有其他条件匹配,将执行默认的匹配分支。match('DEF'){'aaa'=>...,'bbb'=>...,default=>echo'NOmatching:'.$name,};//"NOmatchin:DEFF"匹配表达式mustIfswitch满足条件,不匹配case键,block会默默的执行码流。匹配表达式没有。在一个匹配表达式中,必须有一个匹配该表达式的条件或一个默认条件被处理。如果没有匹配项,并且未设置默认分支,则匹配表达式将引发\UnhandledMatchError异常。$value=3;match($value){1=>'一个',2=>'两个',};当上面的代码执行时,会抛出一个错误:Fatalerror:UncaughtUnhandledMatchErrorin...match\UnhandledMatchError如果表达式没有匹配到,则表达式会抛出异常。\UnhandledMatchError是PHP8中一个新的异常类,它扩展了\Error。对于所有PHP核心异常类的完整层次结构。这个类可以很容易地扩展:classUnhandledMatchErrorextends\Error{}对未处理类型的严格匹配匹配表达式中最重要的设计选择之一是它对未处理类型的匹配。functionread(mixed$key):string{returnmatch($key){1=>'Integer1','1'=>'String1',true=>'Booltrue',[]=>'Emptyarray',[1]=>'Array[1]',};}read(1);//"Integer1"read('1');//典型switch块中的"String1",它的大小写是松散匹配的,即用==。在匹配表达式中,所有匹配的分支都是严格比较(===)匹配的。在上面的代码片段中,每个单独的分支都将匹配其值和类型。匹配任何表达式匹配表达式允许给定值匹配表达式。match($https){404=>'Pagenotfound',Response::REDIRECT=>'Redirect',$client->getCode()=>'ClientError',$response->getCode()=>'ResponseError',默认=>'未知错误'};表达式将按照它们列出的顺序进行评估。匹配表达式将尝试按以下顺序匹配$httpst:1.$httpst===4042.$httpst===Response::REDIRECT3。$httpst===$client->getCode()4.$httpst===$response->getCode()5.default如果找到正匹配,则不会尝试其他分支,直接返回。matchVSswitch向后兼容性影响匹配表达式是PHP8中的新语法。使用匹配表达式的代码在旧的PHP版本中不起作用。