您好,欢迎访问一九零五行业门户网

PHP 8 还有半年就要来了, 来看看有哪些新特性

新的 php 主要版本 php8 预计将于 2020 年底发布。
它现在正处于非常活跃的开发中,所以在接下来的几个月里,开发速度和开发进程可能会有很大的变化。
在这篇文章中,我会罗列出 php8 中会发生的一些改变:新功能、性能改进和突破性变化。
因为 php8 是一个新的主要版本,所以代码及语法向下兼容性会更低。
如果您一直保持与最新版本保持同步,那么升级应该不会太难,因为大多数突破性的更改在 7.* 版本中都已弃用。
除了突破性的变化,php8 还带来了一些不错的新特性,比如 jit 编译器和 union types,当然还有其它更多的特性。
新特性
从新特性开始说起,但是 php8 仍在积极开发中,因此这个清单将随着时间的推移而增长。
联合类型 (union types) rfc
考虑到 php 的动态类型特性,联合类型在很多情况下都很有用。
联合类型是两个或多个类型的集合,这些类型指示可以使用这两个类型中的任何一个。
public function foo(foo|bar $input): int|float;
我怎么感觉这个和 c 语言里的联合体有点相似。
请注意,void 永远不能是联合类型的一部分,因为它表示 “根本没有返回值”。
此外,可以使用 |null 或使用现有的?。
public function foo(foo|null $foo): void;public function bar(?bar $bar): void;
jit rfc
jit-just-in-time 编译器承诺显著提高性能,尽管在 web 应用可能没有较大的好处。
在这一点上还没有任何准确的基准,但它们肯定会出现的。
静态返回类型 (static return type) rfc
虽然已经可以返回 self ,但在 php8 之前,静态不是有效的返回类型。考虑到 php 的动态类型特性,它对许多开发人员都很有用。
class foo{ public function test(): static { return new static(); }}
弱映射 (weak maps) rfc
基于在 php 7.4 中添加的 weakrefs rfc 的基础上,在 php 8 中 添加了 weakmap 实现。weakmap 包含对对象的引用,这不会阻止这些对象被垃圾回收。
以 orm 为例,它们经常实现包含对实体类的引用的缓存,以提高实体之间关系的性能。
这些实体对象不能被垃圾回收,只要该缓存有对它们的引用,即使缓存是唯一引用它们的东西。
如果该缓存层改为使用弱引用和映射,则 php 将在其他对象不再引用这些对象时对它们进行垃圾回收。
特别是在 orm 的情况下,它可以在一个请求中管理数百个 (如果不是数千个) 实体;弱映射可以提供一种更好、更资源友好的方式来处理这些对象。
以下是 weak maps 的用法,rfc 中的一个示例:
class foo { private weakmap $cache; public function getsomethingwithcaching(object $obj): object { return $this->cache[$obj] = $this->computesomethingexpensive($obj); }}
可以在对象上使用::class rfc
一个小而有用的新特性:现在可以对对象使用::class,而不必对它们使用 get_class()。
它的工作方式与 get_class() 相同。
$foo = new foo();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 接口 rfc
stringable 接口可用于键入提示任何字符串或实现__tostring()。
此外,每当类实现__tostring() 时,它都会自动在幕后实现接口,不需要手动实现它。
class foo{ public function __tostring(): string { return 'foo'; }}function bar(stringable $stringable) { /* … */ }bar(new foo());bar('abc');
新的 str_contains () 函数 rfc
有些人可能会说这是早就应该实现的功能,但是我们最终不必再依赖 strpos () 来知道一个字符串是否包含另一个字符串。
以前:
if (strpos('string with lots of words', 'words') !== false) { /* … */ }
现在:
if (str_contains('string with lots of words', 'words')) { /* … */ }
新的 fdiv () 函数 pr
新的 fdiv () 函数的作用类似于 fmod () 和 intdiv () 函数,它们允许被 0 整除。
您将得到 inf、-inf 或 nan ,而不是错误,具体取决于大小写。
新的 get_debug_type () 函数 rfc
get_debug_type () 返回一个变量的类型。
听起来像是 gettype () 可以实现的功能。
get_debug_type () 为数组、字符串、匿名类和对象返回更有用的输出。
例如,在类 \foo\bar 上调用 gettype () 将返回 object。
使用 get_debug_type () 将返回类名。
可以在 rfc 中找到 get_debug_type () 和 gettype () 之间差异的完整列表。
改进 traits 里的抽象方法 rfc
traits 可以指定必须由使用它们的类实现的抽象方法。
但是有一个警告:在 php8 之前,这些方法实现的签名没有经过验证。
在以下代码中有效:
trait test { abstract public function test(int $input): int;}class usestrait{ use test; public function test($input) { return $input; }}
在使用 traits 并实现其抽象方法时,php8 将执行正确的方法签名验证。
这意味着您需要改写以下内容:
class usestrait{ use test; public function test(int $input): int { return $input; }}
token_get_all () 的对象接口 rfc
函数的作用是:返回值的是一个数组。
此 rfc 使用 phptoken::getall () 方法添加一个 phptoken 类。
此实现使用对象,而不是普通值。
它消耗更少的内存,更容易阅读。
变量语法调整 rfc
来自 rfc:“统一变量语法 rfc 解决了 php 变量语法中的一些不一致问题”,这个 rfc 打算解决少数被忽略的情况。
内部函数的类型批注
很多人都参与到为所有内部函数添加适当类型注释的工作中。
这是一个长期存在的问题,通过在以前版本中对 php 所做的所有更改,最终可以解决这个问题。
这意味着内部函数和方法在反射中将具有完整的类型信息。
统一错误类型 rfc
php 中的用户定义函数已经抛出 typeerrors,但是内部函数没有抛出 typeerrors,而是发出警告并返回 null。
从 php8 开始,内部函数的行为已经保持一致。
重新分类 zend engine 报错 rfc
许多以前只触发警告或通知的错误已转换为适当的错误。
以下警告已更改。
未定义变量:错误异常而不是通知。
未定义的数组索引:警告而不是通知。
被零除:divisionbyzeroerror 异常而不是警告。
尝试递增 / 递减非对象的属性‘% s’:错误异常而不是警告。
试图修改非对象的属性‘% s’:错误异常而不是警告。
尝试分配非对象的属性‘% s’:错误异常而不是警告。
从空值创建默认对象:错误异常而不是警告。
正在尝试获取非对象的属性‘% 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 !
串联优先级 rfc
虽然在 php7.4 中已不推荐使用,但此更改现在生效。
如果你这样写的话:
echo "sum: " . $a + $b;
php 以前会这样解释它:
echo ("sum: " . $a) + $b;
php 8 将会这样解释它:
echo "sum: " . ($a + $b);
反射方法签名更改
反射类的三个方法签名已更改:
reflectionclass::newinstance($args);reflectionfunction::invoke($args);reflectionmethod::invoke($object, $args);
现已成为:
reflectionclass::newinstance(...$args);reflectionfunction::invoke(...$args);reflectionmethod::invoke($object, ...$args);
升级指南指定,如果您扩展了这些类,并且仍然希望同时支持 php 7 和 php 8,则允许以下签名:
reflectionclass::newinstance($arg = null, ...$args);reflectionfunction::invoke($arg = null, ...$args);reflectionmethod::invoke($object, $arg = null, ...$args);
推荐教程:《php教程》
以上就是php 8 还有半年就要来了, 来看看有哪些新特性的详细内容。
其它类似信息

推荐信息