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

距离PHP8还有半年,让我们看看有什么新的

时间:2023-03-19 02:22:11 科技观察

PHPPHP8的新大版本预计在2020年底发布。目前开发非常活跃,所以开发的速度和进度可能会有所不同在接下来的几个月里很多。在本文中,我将列出PHP8中将发生的一些变化:新特性、性能改进和重大变化。因为PHP8是新的大版本,代码和语法向后兼容性会比较低。如果您一直在跟上最新版本,升级应该不会太困难,因为大多数重大更改在7.*版本中已弃用。除了突破性的变化,PHP8还带来了一些不错的新特性,比如JIT编译器和联合类型,当然还有更多的特性。新特性从新特性开始,但是PHP8仍在积极开发中,因此这个列表会随着时间的推移而增长。联合类型(Uniontypes)RFC考虑到PHP的动态类型特性,联合类型在很多情况下都很有用。联合类型是两种或多种类型的集合,表示可以使用这两种类型中的任何一种。publicfunctionfoo(Foo|Bar$input):int|float;怎么感觉这有点像C语言中的union。请注意,void永远不能成为联合类型的一部分,因为它意味着“根本没有返回值”。此外,您可以使用|NULL或使用现有的?.publicfunctionfoo(Foo|null$foo):void;publicfunctionbar(?Bar$bar):void;JITRFCJIT-Just-In-Time编译器承诺会显着提高性能,尽管在Web应用程序中好处可能并不大。目前还没有任何准确的基准,但它们肯定会出现。静态返回类型(Staticreturntype)虽然RFC已经可以返回self,但是在PHP8之前,static并不是一个有效的返回类型。鉴于PHP的动态类型特性,它对许多开发人员很有用。classFoo{publicfunctiontest():static{returnnewstatic();}}WeakmapsRFC在PHP8中添加了一个WeakMap实现,基于PHP7.4中添加的WeakRefsRFC。WeakMap包含对对象的引用,这不会阻止这些对象被垃圾收集。以ORM为例,它们通常实现包含对实体类的引用的缓存,以提高实体之间关系的性能。只要缓存有对它们的引用,这些实体对象就不能被垃圾回收,即使缓存是唯一引用它们的东西。如果缓存层改为使用弱引用和映射,PHP将在不再引用其他对象时对其进行垃圾回收。特别是在ORM的情况下,它可以在单个请求中管理数百个(如果不是数千个)实体;弱映射可以提供更好、更资源友好的方式来处理这些对象。下面是Weakmaps的用法,一个来自RFC的例子:);}}可以在对象上使用::classRFC一个小而有用的新功能:现在可以在对象上使用::class而不必在它们上使用get_class()。它的工作方式与get_class()相同。$foo=newFoo();var_dump($foo::class);创建DateTime对象的接口您已经可以使用DateTime::createFromImmutable($immutableDateTime)从DateTimeImmutable对象创建DateTime对象,但反之则很棘手。通过添加DateTime::createFromInterface()和DatetimeImmutable::createFromInterface(),现在有一种通用方法可以将DateTime和DateTimeImmutable对象相互转换。DateTime::createFromInterface(DateTimeInterface$other);DateTimeImmutable::createFromInterface(DateTimeInterface$other);新的Stringable接口RFCStringable接口可用于键入提示任何字符串或实现__toString()。此外,每当一个类实现__toString()时,它会自动在幕后实现接口,无需手动实现。classFoo{publicfunction__toString():string{return'foo';}}functionbar(Stringable$stringable){/*...*/}bar(newFoo());bar('abc');新的str_contains()函数RFC一些人可能会争辩说这早就应该了,但我们终于不必依赖strpos()来知道一个字符串是否包含另一个。之前:if(strpos('stringwithlotsofwords','words')!==false){/*...*/}现在:if(str_contains('stringwithlotsofwords','words')){/*...*/}新的fdiv()函数PR新的fdiv()函数的作用类似于fmod()和intdiv()函数,它们允许被零整除。根据情况,您将得到INF、-INF或NaN而不是错误。新的get_debug_type()函数RFCget_debug_type()返回变量的类型。听起来像gettype()可以做的事情。get_debug_type()为数组、字符串、匿名类和对象返回更有用的输出。例如,在类\foo\Bar上调用gettype()将返回Object。使用get_debug_type()将返回类名。可以在RFC中找到get_debug_type()和gettype()之间差异的完整列表。traits中改进的抽象方法RFCtraits可以指定必须由使用它们的类实现的抽象方法。但有一个警告:在PHP8之前,这些方法实现的签名没有经过验证。在以下代码中有效:traitTest{abstractpublicfunctiontest(int$input):int;}classUsesTrait{useTest;publicfunctiontest($input){return$input;}}当使用traits并实现其抽象方法时,PHP8会执行正确的方法Signature确认。这意味着需要重写如下:classUsesTrait{useTest;publicfunctiontest(int$input):int{return$input;}}token_get_all()的对象接口RFC函数的作用是:返回值是一个数组.此RFC使用PhpToken::getall()方法添加了一个PhpToken类。此实现使用对象,而不是普通值。它消耗更少的内存并且更容易阅读。变量语法调整RFC来自RFC:“TheUniformVariableSyntaxRFCAddressesSomeInconsistenciesinPHPVariableSyntax”,这个RFC旨在解决少数被忽略的情况。内部函数的类型注释许多人都参与了为所有内部函数添加适当的类型注释的工作。这是一个长期存在的问题,随着以前版本对PHP所做的所有更改,它终于得到了解决。这意味着内部函数和方法将在反射中具有完整的类型信息。统一错误类型RFCPHP中的用户定义函数已经抛出TypeErrors,但内部函数不会抛出TypeErrors,而是发出警告并返回NULL。自PHP8以来,内在函数的行为一直保持一致。重新分类的zend引擎错误RFC许多以前只触发警告或通知的错误已转换为适当的错误。以下警告已更改。未定义的变量:错误异常而不是通知。未定义的数组索引:警告而不是通知。除以零:DivisionByZeroError异常而不是警告。尝试增加/减少非对象的属性“%s”:错误异常而不是警告。试图修改非对象的属性“%s”:错误异常而不是警告。尝试分配非对象的属性“%s”:错误异常而不是警告。从null创建默认对象:错误异常而不是警告。正在尝试获取非对象的属性“%s”:警告而不是通知。未定义的属性:%s::$%s:警告而不是通知。无法将元素添加到数组,因为下一个元素已被采用:错误异常而不是警告。无法取消设置非数组变量中的偏移量:错误异常而不是警告。不能将标量值用作数组:错误异常而不是警告。只能解包数组并遍历:TypeError异常而不是警告。提供给foreach()的参数无效:TypeError异常而不是警告。非法偏移类型:TypeError异常而不是警告。isset中的非法或空偏移类型:TypeError异常而不是警告。未设置的非法偏移类型:引发TypeError而不是警告。数组到字符串的转换:警告而不是通知。资源ID#%d用作偏移量,转换为整数(%d):警告而不是通知。发生字符串偏移量转换:警告而不是通知。未初始化的字符串偏移量:%d:警告而不是通知。无法将空字符串分配给字符串偏移量:错误异常而不是警告默认错误报告级别现在是E_ALL,而不是除E_NOTICE和E_DEVERATED之外的所有级别。这意味着许多以前被悄悄忽略的错误可能会弹出,尽管它们可能在PHP8之前就已经存在。@运算符不再忽略致命错误。此更改可能会揭示在PHP8之前隐藏的错误。确保在生产服务器上设置display_errors=off!ConcatenationPriorityRFC尽管在PHP7.4中已弃用,但此更改现已生效。如果你这样写:echo"sum:"。$a+$b;PHP曾经这样解释它:echo("sum:".$a)+$b;PHP8会这样解释它:echo"sum:"。($a+$b);反射方法签名更改反射类的三个方法签名已更改:ReflectionClass::newInstance($args);反射函数::调用($args);ReflectionMethod::invoke($object,$args);现在变成了:ReflectionClass::newInstance(...$args);ReflectionFunction::invoke(...$args);ReflectionMethod::invoke($object,...$args);升级指南指定如果您扩展这些类并且仍然希望同时支持PHP7和PHP8,则允许使用以下签名:ReflectionClass::newInstance($arg=null,...$args);ReflectionFunction::invoke($arg=null,...$args);ReflectionMethod::invoke($object,$arg=null,...$args);