Home > Article > Backend Development > PHP 8 is coming in half a year, let's take a look at what new features it has
The new major version of PHP, PHP8, is expected to be released by the end of 2020.
It is under very active development right now, so the pace and progress of development may vary significantly over the next few months.
In this article, I will list some of the changes that will happen in PHP8: new features, performance improvements, and breaking changes.
Because PHP8 is a new major version, the code and syntax backward compatibility will be lower.
If you've been keeping up with the latest releases, upgrading shouldn't be too difficult, as most breaking changes have been deprecated in the 7.* releases.
In addition to breakthrough changes, PHP8 also brings some great new features, such as the JIT compiler and union types, and of course there are many more features.
New Features
I'll start with new features, but PHP8 is still under active development, so this list will grow over time.
Union types (Union types) RFC
Given the dynamic typing nature of PHP, union types are useful in many situations.
A union type is a collection of two or more types that indicate that either type can be used.
public function foo(Foo|Bar $input): int|float;
Why do I feel that this is somewhat similar to the union in C language.
Please note that void can never be part of a union type because it means "no return value at all".
Also, can you use |NULL or use an existing one? .
public function foo(Foo|null $foo): void; public function bar(?Bar $bar): void;
JIT RFC
The JIT-Just-In-Time compiler promises significant performance improvements, although there may not be a big benefit in web applications.
There aren’t any accurate benchmarks at this point, but they will definitely emerge.
Static return type (Static return type) RFC
Although it is already possible to return self , static was not a valid return type before PHP8. PHP is useful to many developers considering its dynamically typed nature.
class Foo { public function test(): static { return new static(); } }
Weak maps RFC
Based on the WeakRefs RFC added in PHP 7.4, a WeakMap implementation was added in PHP 8. WeakMap contains references to objects, which does not prevent these objects from being garbage collected.
Taking ORMs as an example, they often implement caches containing references to entity classes to improve the performance of relationships between entities.
These entity objects cannot be garbage collected as long as the cache has a reference to them, even if the cache is the only thing referencing them.
If this caching layer uses weak references and mappings instead, PHP will garbage collect these objects when they are no longer referenced by other objects.
Especially in the case of ORMs, which can manage hundreds (if not thousands) of entities in a single request; weak mapping can provide a better, more resource-friendly way to handle these object.
The following is the usage of Weak maps, an example in the RFC:
class Foo { private WeakMap $cache; public function getSomethingWithCaching(object $obj): object { return $this->cache[$obj] ??= $this->computeSomethingExpensive($obj); } }
Can be used on objects::class RFC
A small but useful new feature: Now You can use ::class on objects without having to use get_class() on them.
It works the same as get_class().
$foo = new Foo(); var_dump($foo::class);
Interface for creating DateTime objects
You can already create a DateTime object from a DateTimeImmutable object using DateTime::createFromImmutable($immutableDateTime), but the reverse is tricky.
With the addition of DateTime::createFromInterface() and DatetimeImmutable::createFromInterface(), there is now a universal way to convert DateTime and DateTimeImmutable objects to and from each other.
DateTime::createFromInterface(DateTimeInterface $other); DateTimeImmutable::createFromInterface(DateTimeInterface $other);
New Stringable interface RFC
The Stringable interface can be used to type prompt any string or implement __toString().
Also, whenever a class implements __toString(), it automatically implements the interface behind the scenes and there is no need to implement it manually.
class Foo { public function __toString(): string { return 'foo'; } } function bar(Stringable $stringable) { /* … */ } bar(new Foo()); bar('abc');
New str_contains () function RFC
Some may say this is long overdue, but we finally don’t have to rely on strpos () anymore Know if a string contains another string.
Previously:
if (strpos('string with lots of words', 'words') !== false) { /* … */ }
Now:
if (str_contains('string with lots of words', 'words')) { /* … */ }
New fdiv () function PR
New fdiv () function Acts similarly to the fmod () and intdiv () functions, which allow divisibility by zero.
You will get INF, -INF, or NaN instead of an error, depending on case.
New get_debug_type () function RFC
get_debug_type () returns the type of a variable.
Sounds like something gettype() can do.
get_debug_type () returns more useful output for arrays, strings, anonymous classes, and objects.
For example, calling gettype() on class \foo\Bar will return Object.
Using get_debug_type () will return the class name.
A complete list of differences between get_debug_type () and gettype () can be found in the RFC.
Improve abstract methods in traits RFC
traits can specify abstract methods that must be implemented by the classes that use them.
But there is a warning: before PHP8, the signatures of these method implementations were not verified.
在以下代码中有效:
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教程》
The above is the detailed content of PHP 8 is coming in half a year, let's take a look at what new features it has. For more information, please follow other related articles on the PHP Chinese website!