尽管新版本的PHP很小,但它已经为语言的语法及其性能带来了许多新的,毫不夸张的酷功能。 创新的清单不是最终的,但是主要的变更已经完成并被接受。 该版本计划于2019年12月发布。

即将发布的版本的主要更改:
- 类型化类的属性
- 预加载以获得更好的性能
- 箭头函数,用于简短编写匿名函数
- 为联合运算符分配空值(?? =)
- 传统方法签名中的协方差/矛盾
- 外部函数接口为开发PHP扩展提供了新的可能性
- 数组中的拆包运算符
阅读有关猫的这些和其他更改的更多信息。
免责声明:在与同事的讨论中,布伦特(Brent)的文章“ PHP 7.4的新功能”多次出现。 起初我想进行翻译,但是在此过程中,我意识到并不是所有的最新更新都在文本中指出,并且存在一些错误,因此本文出现了,而不是翻译。箭头功能( RFC )
箭头函数使您可以简短记录匿名函数:
array_map(function (User $user) { return $user->id; }, $users) array_map(fn(User $user) => $user->id, $users)
采用的箭头功能实现的一些功能:
- 他们可以访问
parent
作用域,因此无需使用use关键字。 $this
也可以使用,就像常规匿名函数中一样。- 箭头函数只能包含一行,它也是返回运算符。
您可以在有关Habr的这篇
文章中了解有关它们的更多信息。
类型化属性( RFC )
万岁! 类属性现在可以具有类型提示。 自PHP 7以来,这是一个期待已久的更改,旨在实现更强的语言键入。 现在,我们具有用于强类型键入的所有基本功能。 除
void
和
callable.
外,所有类型都可以键入
callable.
class Bar { public string $name; public ?int $amount; public Foo $foo; }
如果您想让我更详细地考虑键入对象属性的新可能性,请在注释中注明,我将撰写有关它们的单独文章!
分配空联接运算符( RFC )
代替这么长的条目:
$data['date'] = $data['date'] ?? new DateTime();
现在可以这样写:
$data['date'] ??= new DateTime();
数组拆包运算符( RFC )
现在,您可以在数组中使用unpack运算符:
$arrayA = [1, 2, 3]; $arrayB = [4, 5]; $result = [0, ...$arrayA, ...$arrayB, 6 ,7]; <i>// [0, 1, 2, 3, 4, 5, 6, 7]</i>
请注意,这仅适用于非关联数组。
外部功能接口( RFC )
外部功能接口(FFI)允许您直接在PHP代码中编写C代码。 这意味着PHP扩展可以用纯PHP编写。
应当指出,这是一个复杂的话题。 您仍然需要C的知识才能正确使用这些功能。
预加载是PHP内核的一个了不起的补充,它应该导致一些显着的性能改进。
例如,如果您使用框架,则必须为每个请求下载并重新编译其文件。 使用opcache时-第一次将这些文件包含在请求的处理中,然后每次成功检查它们的更改。 预加载允许服务器在启动时将指定的PHP文件加载到内存中,并使它们始终可用于所有后续请求,而无需进行其他文件更改检查。
性能改进不是“免费的”-如果修改了预加载的文件,则必须重新启动服务器。
遗留方法签名( RFC )中的协方差/矛盾
当前,PHP具有不变的参数类型和不变的返回类型。 此更改使您可以将参数的类型更改为其超类型之一。 反过来,返回的类型可以用其子类型代替。 因此,这一改变将允许更严格地遵循代换原则。
使用协变返回类型的示例:
interface Factory { function make(): object; } class UserFactory implements Factory { function make(): User; }
和相反的论点:
interface Concatable { function concat(Iterator $input); } class Collection implements Concatable { function concat(iterable $input) {/* . . . */} }
自定义对象序列化( RFC )
有两种新的魔术方法可用:
__serialize
和
__unserialize
。 这种序列化机制将
Serializable
接口的多功能性与实现
__sleep/__wakeup
方法的方法结合在一起。 有关它们之间差异的更多详细信息,请参见RFC。
串联优先级( RFC )
如果您这样写:
echo "sum: " . $a + $b;
PHP现在将其解释为:
echo ("sum: " . $a) + $b;
PHP 8将对此做出不同的解释:
echo "sum :" . ($a + $b);
PHP 7.4在检测到包含“。”的表达式时添加了过时警告。 在“ +”或“-”之前,且不要用方括号括起来。
__toString
( RFC )异常支持
以前,无法从
__toString
magic方法引发异常。 此行为的基本原理是,在标准库的许多功能中都执行了对象到字符串的转换,并且并非所有对象都准备好正确地“处理”异常。 作为该RFC的一部分,对代码库中的字符串转换进行了全面的审核,现在可以删除此限制。
链接反射( RFC )
库,例如
symfony/var-dumper
,严重依赖
ReflectionAPI
来准确显示变量。 以前,对链接反射没有适当的支持,这迫使这些库不得不依靠黑客来检测链接。 PHP 7.4添加了一个
ReflectionReference
类来解决此问题。
添加了mb_str_split
( RFC )方法
此函数提供与
str_split
相同的功能,但适用于以多字节编码编写的字符串。
始终可用的ext-hash
扩展( RFC )
现在,此扩展在所有PHP安装中始终可用。
不再积极支持PEAR,核心团队决定从PHP 7.4的默认安装中删除它。
密码哈希算法注册表( RFC )
添加了新的
password_algos
函数,该函数返回所有已注册密码哈希算法的列表。
弱链接( RFC )
弱链接使您可以保存到对象的链接,该链接不会阻止该对象的破坏。 例如,它们对于实现类似缓存的结构很有用。
数字文字定界符( RFC )
数字组中缺少可视分隔符会增加读取和调试代码的时间,并可能导致意外错误。 现在添加了对数字文字中下划线字符的支持,以在视觉上分隔数字组。
1_000_000_000 // int 6.674_083e-11; // float 299_792_458; // decimal 0xCAFE_F00D; // hexadecimal 0b0101_1111; // binary 0137_041; // octal
不建议使用短开放标签( RFC )
短标签
<?
已弃用,并将在PHP 8中删除。短标记
<?= (echo)
不受影响。
左协三元运算符已淘汰( RFC )
三元运算符在PHP中有一些奇怪的怪癖。 该RFC不赞成使用嵌套三元运算符。
1 ? 2 : 3 ? 4 : 5; // deprecated (1 ? 2 : 3) ? 4 : 5; // ok
在PHP 8中,这样的记录将导致编译级错误。
向后不兼容的更改( 升级 )
以下是一些最重要的向后不兼容的更改:
- 在不带父类的类中,对
parent::
的调用已被弃用。 - 在
DateTime
或DateTimeImmutable
实例上调用var_dump
不再使对象属性可用。 - 在由OpenSSL库引起的错误情况下,
openssl_random_pseudo_bytes
将引发异常。 以前,它返回false,这可能导致生成空字符串。 - 尝试序列化
PDO
或PDOStatement
的实例将引发Exception
而不是PDOException
。 - 在
ArrayObject
实例上调用get_object_vars()
ArrayObject
返回ArrayObject
本身的属性,而不是包装的数组的值。 要像以前一样获取包装的数组值, ArrayObject
为array
类型。