属性钩子即将在 PHP 8.4 中成为现实
最后更新于 作者 Paul Redmond
The 属性钩子 RFC 已经通过了一个重要的里程碑,获得了压倒性的积极投票,34 票赞成,仅 1 票反对。这远远超过了通过所需的 2/3 多数票。
PHP 中的属性钩子是什么?
这是 RFC 中的 提案摘要
开发人员经常使用方法来包装和保护对对象属性的访问。对于这种逻辑,有几种非常常见的模式,在实践中,重复实现这些模式可能很冗长。或者,开发人员可以使用 __get 和 __set 来通用地拦截读取和写入,但这是一种笨拙的方法,会无条件地拦截所有未定义的(以及一些已定义的)属性。属性钩子为常见的属性交互提供了一个更具针对性、更专门的工具…
此 RFC 引入了两个“钩子”来覆盖属性的默认“get”和“set”行为。虽然在最初版本中没有包含,但设计包括在将来支持更多钩子的能力。
属性钩子受 Kotlin、C# 和 Swift 等语言的启发,语法包括两种类似于短闭包和多行闭包的语法变体
class User implements Named{ private bool $isModified = false; public function __construct( private string $first, private string $last ) {} public string $fullName { // Override the "read" action with arbitrary logic. get => $this->first . " " . $this->last; // Override the "write" action with arbitrary logic. set { [$this->first, $this->last] = explode(' ', $value, 2); $this->isModified = true; } }}
语法不要求始终一起定义两个钩子;事实上,这里是一个 RFC 中仅定义 set
的示例
class User{ public string $name { set { if (strlen($value) === 0) { throw new ValueError("Name must be non-empty"); } $this->name = $value; } } public function __construct(string $name) { $this->name = $name; }}
你可以在 RFC 中阅读有关 PHP 中属性钩子的所有详细信息。此功能看起来很可能在 PHP 8.4 中发布。如果你想查看此功能的讨论和进展,实现已经是一个 草案拉取请求。