PHP 8.1 有什么新变化?

PHP 8.1 于 2021 年 11 月发布,是 PHP 语言的最新次要版本。除了一些较小的改进和性能增强之外,它还添加了几个新的语言功能。有一些重大更改需要注意,但 PHP 8.0 的大多数升级应该很简单。

新功能
今年的 PHP 更新添加了多项新功能以提高开发人员的工作效率。以下是您升级后可以使用的内容。

枚举
枚举类型最终成为 PHP 语言的一部分。它们让您指定一个值必须是一组预定义常量中的一个。

与常规常量相比,枚举在用作方法参数和返回值时为您提供了内置验证。它们也可能具有附加行为的支持值和方法。

PHP 8.0类PostStatus {

const Draft =  1 ; 
常量发布=  2 ; } # PHP 8.0 - 不能打字提示必须在`PostStatus` 中定义`$PostStatus` 

的值
。class Post {
public function __construct (
public string $Headline ,
public int $PostStatus ) { } } # PHP 8.1 enum PostStatus {
case Draft = 1 ;
案例发布= 2 ; } # PHP 8.1 - 现在不可能传递

无效值作为状态。class Post {

public  function __construct ( 
    public string $Headline , 
    public PostStatus $PostStatus )  { } }

只读属性
在新的readonly关键字标记的类属性的不可变的。只读属性只能写入一次。尝试在初始化后更改它们的值将引发错误。

这简化了简单的不可变值对象的创建。以前,如果您想公开属性值而不允许修改,则需要向类添加重复的方法。现在,您可以在public不冒意外突变风险的情况下制作这些属性。

PHP 8.0 - 这很快就会变得重复!class Post {

public  function __construct ( 
    protected string $Headline )  { } 
公共 函数getHeadline ( )  : string { 
    return  $this  ->  Headline ; 
} } # PHP 8.1 class Post { 
public  function __construct ( 
    public readonly string $Headline )  { } }

交叉路口类型
PHP 的类型系统现在可以理解交叉点。这些使您可以指定一个值必须实现多个接口。

这在代码需要调用由两个不同接口定义的实例方法的情况下很有用。以前,您需要创建一个扩展两个所需接口的新接口。在您无法修改目标类以实现新接口的情况下,这并不总是可行的。

交叉点是通过将两种或多种类型与符号字符组合在一起来定义的。在 PHP 8.0 中引入联合类型后,它们为类型系统增加了更多的灵活性。一个警告是你目前不能同时使用交集和联合类型——Countable&Stringable|CustomType在这个版本中是禁止的。

PHP 8.0接口CountableString extends Countable , Stringable { } 公共 函数countAndReport ( CountableString $value ) : void {

echo  “ $value:”  。 计数( $value ) ; } # PHP 8.1公共 函数countAndReport ( Countable & Stringable $value )  : void { 
echo  " $value :"  .  计数( $value ) ; }

纤维
纤程是促进并发执行的机制。它们使实现可从堆栈中的任何位置挂起的可恢复代码块变得更加容易。

该纤维API是相对水平较低。预计最终用户开发人员不会定期与它进行交互。相反,Fibers 将被集成到提供异步 API 和事件循环实现的库中。它们是一个控制流系统,可以简化更高级别的抽象。

Fibers 提供了一条异步函数调用的路径,看起来像常规的同步操作。您可以删除与承诺和回调相关的样板。Fiber 在适当的点处理暂停和恢复代码,为操作的阻塞和非阻塞实现提供一种 API。

PHP 8.0 - 基于承诺的 HTTP 客户端$response = $httpClient -> request ( “http://example.com” )

->  then ( function  ( Response $Response )  { 
    return  $Response  ->  getBody ( ) ; 
} ) ; 打印 $response ; # PHP 8.1 - 内部使用 Fibers 的 HTTP 客户端$response  =  $httpClient  ->  request ( "https://example.com" ) ; 打印 $response  ->  getBody ( ) ;

一流的可调用对象
Callables 现在是 PHP 语言中的一等公民。这意味着您可以直接将函数分配给变量,而无需使用旧的数组语法或显式的闭包创建。

这种变化在函数式编程上下文中最有用。通过直接变量赋值,传递函数更清晰、更容易。

PHP 8.0 $builtin = Closure

:: fromCallable ( “array_filter” ) ;
$method = [ $this , “getData” ] ;

PHP 8.1 $builtin = array_filter ( … ) ;

$method = $this -> getData ( … ) ;
该…替换函数的参数是语法的必需部分。这表示您希望将函数分配给变量,而不是调用函数并分配其返回值。

在初始化器中使用 New
另一个新功能是new初始化程序中的关键字。您现在可以使用对象实例作为默认参数值:

PHP 8.0 class SendNewsletterAction {

protected Mailer $Mailer ; 
公共 函数__construct ( ?Mailer $Mailer = null )  { 
    $this  ->  Mailer  =  $Mailer ?? 新的SmtpMailer ( ) ; 
} } # PHP 8.1 class SendNewsletterAction { 
public  function __construct ( 
    protected readonly Mailer $Mailer = new SmtpMailer ( ) )  { } }

该new关键字也适用于静态变量、全局常量和属性参数。当您想要一个对象实例作为默认值时,它为您提供了更大的灵活性和便利性。

最终类常量
该final关键字现在支持类的常量。您可以将单个常量标记为final不密封整个类。以前子类可以自由地覆盖从父类继承的常量的值。

#PHP 8.0 -没有不能禁止这些
#使全班final类DemoClass {
公共 常量DemoConstant = 1 ; }类ChildClass延伸DemoClass {
公共 常量DemoConstant = 2 ; } # PHP 8.1 - 只有常量可以是final。类DemoClass {
最终公共 常量DemoConstant = 1 ; } class ChildClass extends DemoClass {
// 引发致命错误
public const DemoConstant = 2 ; }
其他
除了上面列出的重要项目之外,PHP 8.1 还添加了一些方便的功能,有助于使代码更加自文档化。您可以使用显式符号(例如 )编写八进制数0o14,并使用新的never返回类型来表示将引发异常或退出当前脚本的函数。这有助于通知静态分析软件中的死代码检测。

标准库中有一些新函数。array_is_list()让您检查数组是列表 ( [“foo”, “bar”]) 还是关联 ( [“foo” => “bar”]),为现有用户区代码中常见的函数提供内置实现。fsync()并fdatasync()让您将文件指针更改同步回底层存储介质。还添加了对 XChaCha20 和 Ristretto255 哈希算法的钠支持。

最后,此版本带来了性能改进的前景。包括类继承缓存在内的优化可以免费提供高达 8% 的性能提升。这在具有许多父子关系的大量面向对象的代码库中最为明显。PHP 现在将缓存这些链接,因此它不会不断地重建它们。

向后不兼容的变化
作为次要版本升级,在升级之前需要注意一些重大更改和弃用。以下是最有可能在您的代码库中出现问题的问题:

G L O B A L S 不 再 允 许 覆 盖 数 组 。 您 仍 然 可 以 写 入 单 个 键 , 但 不 能 重 新 分 配 _GLOBALS不再允许覆盖数组。您仍然可以写入单个键,但不能重新分配 GLOBALS_GLOBALS自身。

如果您扩展一个内置类,您的重写方法必须声明一个与原始方法兼容的返回类型。如果您指定了不兼容的类型,则会发出弃用警告。#[ReturnTypeWillChange]对于需要支持多个 PHP 版本的库,当前支持使用属性来避免这种情况。

传递null给内部函数的不可为空参数已被弃用。这以前是允许的,但与用户创建的函数的类型提示强制不一致。

隐式转换 from inttofloat已被弃用 - 这会影响诸如 的情况$array[10.1],其中尾数将丢失,因为数组必须具有整数键。

作为 PHP 正在进行的删除resource类型工作的一部分,几个函数组现在使用新对象而不是资源。这些更改适用于 FileInfo、FTP、IMAP、LDAP、PgSQL 和 PSpell API。

处理 HTML 实体的函数,例如htmlspecialchars()和htmlentities()现在默认情况下转义撇号,因此’将变为’.

不推荐直接调用 trait 的静态方法;您应该在使用 trait 的类上调用该方法。

其他删除和弃用会影响单个 API,包括 PDO、MySQLi 和标准。在升级项目之前,您应该查看整个迁移指南。

综合来看,这个周期的变化是相当无害的。已经符合现代 PHP 最佳实践的代码库在迁移到 8.1 时应该不会遇到太多问题。包括 Symfony 和 Laravel 在内的流行框架也已经支持 PHP 8.1。

结论
PHP 8.1 添加了许多新功能,使开发体验更轻松、更流畅。枚举长期以来一直是类型系统中缺失的一部分,而只读属性和new初始化程序将使编写新类更快。

Fibers 有助于使异步 PHP 更易于使用,而一流的可调用对象有助于在练习函数式编程技术时简化函数引用。所有这些变化进一步使 PHP 作为一种灵活的语言更加成熟,它为您的代码提供强大的安全保证,同时仍然易于使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mikes zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值