属性钩子在 PHP 8.4 中越来越接近现实
属性钩子(Property Hooks)的 RFC 通过了一个重要的里程碑,获得了压倒性的 34 张赞成票和 1 张反对票。这远远高于通过所需的 ⅔ 多数票。
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 中可能会落地。如果想了解此功能的讨论和进展情况,那么该实现已经是一个 PR 草案。