站长资讯网
最全最丰富的资讯网站

PHP8.1新特性大讲解之readonly properties只读属性

本文系翻译,原文地址:https://stitcher.io/blog/php-81-readonly-properties

PHP 8.1:只读属性

多年来,用 PHP 编写数据传输对象和值对象变得非常容易。以 PHP 5.6 中的 DTO 为例:

class BlogData {     /** @var string */     private $title;          /** @var Status */     private $status;          /** @var DateTimeImmutable|null */     private $publishedAt;        /**     * @param string $title      * @param Status $status      * @param DateTimeImmutable|null $publishedAt      */     public function __construct(         $title,         $status,         $publishedAt = null     ) {         $this->title = $title;         $this->status = $status;         $this->publishedAt = $publishedAt;     }          /**      * @return string       */     public function getTitle()     {         return $this->title;         }          /**      * @return Status       */     public function getStatus()      {         return $this->status;         }          /**      * @return DateTimeImmutable|null       */     public function getPublishedAt()      {         return $this->publishedAt;         } }

并将其与PHP 8.0的等价物进行比较:

class BlogData {     public function __construct(         private string $title,         private Status $status,         private ?DateTimeImmutable $publishedAt = null,     ) {}          public function getTitle(): string     {         return $this->title;         }          public function getStatus(): Status      {         return $this->status;         }          public function getPublishedAt(): ?DateTimeImmutable     {         return $this->publishedAt;         } }

这已经很不一样了,尽管我认为仍然存在一个大问题:所有这些吸气剂。就个人而言,自 PHP 8.0 及其提升的属性以来,我不再使用它们。我只是更喜欢使用公共属性而不是添加 getter:

class BlogData {     public function __construct(         public string $title,         public Status $status,         public ?DateTimeImmutable $publishedAt = null,     ) {} }

面向对象的纯粹主义者不喜欢这种方法:对象的内部状态不应该直接暴露,并且绝对不能从外部改变。

在我们在 Spatie 的项目中,我们有一个内部风格指南规则,即不应从外部更改具有公共属性的 DTO 和 VO;一种似乎效果很好的做法,我们已经做了很长一段时间了,没有遇到任何问题。

然而,是的;我同意如果语言确保公共属性根本不会被覆盖会更好。好吧,PHP 8.1通过引入readonly关键字解决了所有这些问题:

class BlogData {     public function __construct(         public readonly string $title,         public readonly Status $status,         public readonly ?DateTimeImmutable $publishedAt = null,     ) {} }

这个关键字基本上就像它的名字所暗示的那样:一旦设置了一个属性,它就不能再被覆盖:

$blog = new BlogData(     title: 'PHP 8.1: readonly properties',      status: Status::PUBLISHED,      publishedAt: now() ); $blog->title = 'Another title'; Error: Cannot modify readonly property BlogData::$title

知道当一个对象被构造时,它不会再改变,在编写代码时提供了一定程度的确定性和平静:一系列不可预见的数据更改根本不会再发生。

当然,您仍然希望能够将数据复制到新对象,并可能在此过程中更改某些属性。我们将在本文后面讨论如何使用只读属性来做到这一点。首先,让我们深入了解一下它们。

您想要了解

赞(0)
分享到: 更多 (0)
网站地图   沪ICP备18035694号-2    沪公网安备31011702889846号