当前位置: 首页 > 后端技术 > PHP

PHP8新特性盘点

时间:2023-03-30 02:13:50 PHP

PHP8.0.0已经正式发布,这对于PHPer来说无疑是一个振奋人心的消息。它包含许多新功能和优化,包括命名参数、联合类型、注释、构造函数属性提升、匹配表达式、nullsafe运算符、JIT,以及改进的类型系统、错误处理和语法一致性。最人性化的功能:命名参数、关节类型和混合类型。这些新特性使得PHP在强类型方面进一步提升,对PHPDoc注解的依赖越来越弱。代码作为文档的好处是开发者最头疼的问题。事情终于有了偷懒的办法。命名参数命名参数可以使函数或方法调用更清晰、更直观。对于下面的函数定义functionfoo(string$a,string$b,?string$c=null,?string$d=null){/*…*/}可以通过下面的方式传入参数来调用foo(b:'值b',a:'值a',d:'值d',);最大的好处是传入参数的顺序和定义的一样Irrelevant,也可以混合参数(但不推荐)。与之前的PHPDoc声明类型组合相比,联合类型现在可以替换为原生支持的联合类型声明,可以在实际运行中验证。PHP7classNumber{/**@varint|float*/private$number;/***@paramfloat|int$number*/publicfunction__construct($number){$this->number=$number;}}新数字('NaN');//OKPHP8classNumber{publicfunction__construct(privateint|float$number){}}newNumber('NaN');//TypeErrornewmixed类型mixed本身是以下类型之一:ArrayBoolCallableIntFloatNullObjectResourceString注意mixed也可以作为参数或属性类型,而不仅仅是返回类型。此外,由于mixed已经包含null,因此不允许将其设置为nullable。以下将触发错误://Fatalerror:Mixedtypescannotbenullable,nullisalreadypartofthemixedtype.functionbar():?mixed{}贡献最大的特性:JITJIT作为PHP底层编译引擎,对于PHP8的性能贡献是非常大的,但是对于常规的WEB应用,优势并不明显,但仍然是一个非常高大上的功能,是PHP8的杰作。PHP8引入了两个即时编译引擎。TracingJIT在两者中具有更大的潜力,在综合基准测试中表现出三倍的性能,在一些长时间运行的程序中表现出1.5-2倍的性能提升。典型的应用程序性能与PHP7.4相当。关于JIT对PHP8性能的贡献最有用的特性:构造函数属性提升、Nullsafe运算符、str_contains()、str_starts_with()、str_ends_with()构造函数属性提升这种新语法糖用于创建值对象或数据传输对象。PHP现在可以将它们组合为一个,而不是为类属性和构造函数指定它们。而不是下面的代码:classMoney{publicCurrency$currency;公共诠释$金额;公共函数__construct(Currency$currency,int$amount,){$this->currency=$currency;$this->金额=$金额;}}您可以这样做:classMoney{publicfunction__construct(publicCurrency$currency,publicint$amount,){}}nullsafe运算符现在可以与新的nullsafe运算符链接,无需对null进行条件检查。如果链中的一个元素失败,则整个链将中止并被视为Null。$country=null;if($session!==null){$user=$session->user;如果($user!==null){$address=$user->getAddress();if($address!==null){$country=$address->country;}}}简化为一行代码$country=$session?->user?->getAddress()?->country;这真的很酷str_contains()、str_starts_with()和str_ends_with()函数有些人可能会说它早就应该了,但我们终于不必依赖strpos()来知道一个字符串是否包含另一个字符串。而不是以下内容:if(strpos('stringwithlotsofwords','words')!==false){/*...*/}你可以这样做if(str_contains('stringwithlotsofwords','words')){/*...*/}感觉大部分场景不应该用strpos。其他两个功能应该早就可用了。str_starts_with()和str_ends_with()这两个函数现在可以省去很多麻烦。str_starts_with('干草堆','干草');//truestr_ends_with('haystack','stack');//true最有潜力的特性:注解、Match表达式、WeakMap注解现在可以在原生PHP语法结构化元数据中使用,不再需要依赖PHPDoc解析,性能也得到提升。之前可能需要定义注解路由:classPostsController{/***@Route("/api/posts/{id}",methods={"GET"})*/publicfunctionget($id){/*...*/}}现在可以直接使用PHP注解语法定义,直接通过反射获取classPostsController{#[Route("/api/posts/{id}",methods:["GET"])]publicfunctionget($id){/*...*/}}匹配表达式可以说是switch表达式的老大哥:match可以有返回值,不需要break语句,可以组合条件,使用严格类型compare,并且不执行任何类型的强制。像这样:$result=match($input){0=>"hello",'1','2','3'=>"world",};WeakMapWeakMap保留对不阻止这些对象被垃圾收集的对象的引用。以ORM为例,它们通常实现缓存以保存对实体类的引用,以提高实体之间关系的性能。只要缓存引用了这些实体对象,就不能对其进行垃圾回收,即使缓存是引用它们的唯一对象。如果此缓存层改为使用弱引用和映射,PHP将垃圾收集这些对象,就好像没有其他对它们的引用一样。尤其是在ORM的情况下,它可以管理数百个(如果不是数千个)请求中的实体;weakmaps可以提供更好、更资源友好的方式来处理这些对象。下面是一个弱映射的例子:classFoo{privateWeakMap$cache;publicfunctiongetSomethingWithCaching(object$obj):object{return$this->cache[$obj]??=$this->computeSomethingExpensive($obj);}}}其他特性0=='foobar'finallyreturnsfalse我们知道在PHP7中0=='foobar'//returnstrue现在终于看起来更合乎逻辑了0=='foobar'//Returnsfalse可以用在对象A中在对象上使用::class的小而有用的新功能:::class现在可以在对象上使用,其工作方式与get_class()相同。$foo=newFoo();var_dump($foo::class);Traits中的抽象方法改进Traits可以指定必须由使用它们的类实现的抽象方法。在PHP8中,必须保持一致的方法定义,包括参数类型和返回类型。traitMyTrait{abstractprivatefunctionneededByTheTrait():string;publicfunctiondoSomething(){returnstrlen($this->neededByTheTrait());}}类TraitUser{使用MyTrait;//这是允许的:privatefunctionneededByTheTrait():string{}//这是禁止的(不正确的返回类型)privatefunctionneededByTheTrait():stdClass{}//这是禁止的(非静态改为静态)privatestaticfunctionneededByTheTrait():字符串{}}