【PHP】PHP 8.1 的新特性一览 | 交叉类型、枚举、never 返回类型、Fibers 纤程、readonly 只读属性

(159) 2024-04-22 17:01:01

目录

    • 一、前言
    • 二、PHP 8.1 新特性
      • 纯交叉类型 Pure Intersection Types
      • 枚举 Enums
      • `never` 返回类型
      • Fibers 纤程
      • readonly 只读属性
    • 三、总结

一、前言

PHP 8.1 发布于2021 年 11 月 25 日,最近一次更新在2022 年 9 月 29 日,我们这次介绍一下这个版本的新特性。

如果你的项目正在使用 8.1 版本,请你要注意这些并且加以运用。

【PHP】PHP 8.1 的新特性一览 | 交叉类型、枚举、never 返回类型、Fibers 纤程、readonly 只读属性 (https://mushiming.com/)  第1张

二、PHP 8.1 新特性

纯交叉类型 Pure Intersection Types

PHP 8.1 增加了对交叉类型的支持。 它类似于 PHP 8.0 中引入的联合类型,但它们的用途恰恰相反。

为了更好地理解它的用法,我们看下 PHP 中类型声明的工作原理。

你可以将类型声明添加到函数参数、返回值和类属性。 此分配称为类型提示,并确保该值在调用时具有正确的类型。 否则,它会立即抛出 TypeError。

但是,声明单一类型有局限性。 联合类型允许声明具有多种类型的值,并且输入必须满足至少一种声明的类型。

请注意使用 & (AND) 运算符来声明交叉类型。 相比之下,我们使用 | (OR) 运算符来声明联合类型。

在交集类型中使用大多数标准类型将导致永远无法实现的类型(例如整数和字符串)。 因此,交叉类型只能包括类类型(即接口和类名)。

下面是如何使用交叉类型的示例代码:

class PureIntersectionTypesClass { 
   

    private Traversable&Countable $countableIterator;
 
    public function setIterator(Traversable&Countable $countableIterator): void { 
   
        $this->countableIterator = $countableIterator;
    }
 
    public function getIterator(): Traversable&Countable { 
   
        return $this->countableIterator;
    }
}

在上面的代码中,我们定义了一个变量 countableIterator 作为两种类型的交集:Traversable 和 Countable。 在这种情况下,声明的两种类型都是接口。

交叉类型也符合已经用于类型检查和继承的标准 PHP 变化规则。 但是还有两个额外的规则来说明交叉类型如何与子类型交互。

PHP 8.1 不能在同一个声明中组合联合类型和交叉类型。 因此,它的实现被称为“纯”交叉类型。

枚举 Enums

编程语言中最常见的枚举示例是布尔类型,其中 true 和 false 作为两能的值。

enum Suit { 
   
  case Hearts;
  case Diamonds;
  case Clubs;
  case Spades;
}

在这里,Suit 枚举定义了四个可能的值:Hearts、Diamonds、Clubs 和 Spades。 您可以使用以下语法直接访问这些值:Suit::Hearts、Suit::Diamonds、Suit::Clubs 和 Suit::Spades。

枚举是在类和对象之上构建的。 枚举与类、接口和特征共享相同的命名空间。

上面提到的枚举称为纯枚举。

如果您想为任何情况提供标量等效值,您还可以定义支持的枚举。 但是,支持的枚举只能具有一种类型,即 int 或 string(从不同时具有两种类型)。

enum Suit: string { 
   
  case Hearts = 'H';
  case Diamonds = 'D';
  case Clubs = 'C';
  case Spades = 'S';
}

注意,支持枚举的所有不同情况都必须具有唯一值。

never 返回类型

PHP 8.1 添加了一个名为 never 的新返回类型提示。 在总是抛出或退出的函数中使用它非常有帮助。

function redirect(string $uri): never { 
   
    header('Location: ' . $uri);
    exit();
}
 
function redirectToLoginPage(): never { 
   
    redirect('/login');
}

never 返回类型的函数应满足三个条件:

  • 不应该明确定义 return 语句。
  • 不应该隐式定义 return 语句(例如 if-else 语句)。
  • 必须以退出语句(显式或隐式)结束其执行。

never返回类型与 void 返回类型有许多相似之处。 它们都确保函数或方法不返回值。 但是,它通过执行更严格的规则而有所不同。 例如,一个 void 声明的函数仍然可以在没有显式值的情况下返回,但你不能对一个never返回类型的函数做同样的事情。

Fibers 纤程

从历史上看,PHP 代码几乎总是同步代码。 代码执行会暂停,直到返回结果,即使对于 I/O 操作也是如此。 您可以想象为什么这个过程可能会使代码执行速度变慢。

Fiber 是 PHP 通过虚拟线程(或绿色线程)处理并行性的方式。 它试图通过允许 PHP 函数中断而不影响整个调用堆栈来消除同步和异步代码之间的差异。

我们可以使用 Fibers 开发全栈、可中断的 PHP 函数,然后可以使用这些函数在 PHP 中实现协作式多任务处理。

【PHP】PHP 8.1 的新特性一览 | 交叉类型、枚举、never 返回类型、Fibers 纤程、readonly 只读属性 (https://mushiming.com/)  第2张

$fiber = new Fiber(function (): void { 
   
    $value = Fiber::suspend('fiber');
    echo "Value used to resume fiber: ", $value, "\n";
});
 
$value = $fiber->start(); //启动
 
echo "Value from fiber suspending: ", $value, "\n";
 
$fiber->resume('test'); //恢复

上面的示例输出如下。

Value from fiber suspending: fiber
Value used to resume fiber: test

readonly 只读属性

PHP 8.1 增加了对只读属性的支持。 它们只能从声明它们的范围初始化一次。 初始化后,您将无法修改它们的值。 这样做会引发错误异常。

class Test { 
   
    public readonly string $kinsta;
 
    public function __construct(string $kinsta) { 
   
        // 初始化
        $this->kinsta = $kinsta;
    }
}

readonly 属性在类内部和外部都提供了强大的不变性保证。

三、总结

PHP 8.1 的新特性很多,我们可以把重点放在

  • 枚举
  • never类型
  • 交叉类型
  • 只读属性
THE END

发表回复