免费部署自己的网站:PHP8还有半年就要来了,来看看有哪些新特性
本文摘要: 新的 PHP 主要版本 PHP8 预计将于 2020 年底发布。它现在正处于十分活跃的开发中,所以在接下来的几个月里,开发速度和开发进程可能会有很大的变化。在这篇文章中,我会罗列出 PHP8 中会发生的一些改变:新功用、性能改善和打破
新的 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);

【免责声明】本文仅代表作者或发布者个人观念,不代表(www.lmnkf.cn)及其所属公司官方发声,对文章观念有疑义请先联络作者或发布者自己修正,若内容触及侵权或违法信息,请先联络发布者或作者删除,若需我们协助请联络平台管理员,Emailcxb5918(本平台不支撑其他投诉反馈渠道,谢谢合作)。若需要学习以上相关常识请到巨推学院观看视频教程,网站地址www.tsllg.cn。

相关内容