导读:
readonly 属性是在 PHP8.1 中实现的,但是这个 readonly 修饰符现在也可用于类。
无需为每个属性设置只读,您将能够严格操作类本身。
以下是相关 RFC,Readonly classes的中文说明。
PHP RFC:只读类
简介
PHP 8.1现在支持 readonly 属性。
但是,例如,声明一个具有许多属性的不可变类仍然很烦人。
因此,此 RFC 建议支持只读类。
提议
允许在 PHP8.1 中添加的只读也适用于类。
PHP8.2
readonly class Test {
public string $prop;
}
这使得类中的所有属性都是只读的。它还禁止创建动态属性。
readonly class Foo{
public int $bar;
public function __construct() {
$this->bar = 1;
}
}
$foo = new Foo();
$foo->bar = 2; // Fatal Error: Uncaught Error: Cannot modify readonly property Foo::$bar
$foo->baz = 1; // Fatal Error: Uncaught Error: Cannot create dynamic property Foo::$baz
另外,在Deprecate dynamic properties#[AllowDynamicProperties]的 RFC 中,支持通过指定继续使用动态属性,但禁止为 readonly 类指定。
#[AllowDynamicProperties]
readonly class Foo {
}
// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo
限制
你不能声明无类型或静态属性。
readonly class Foo{
public $bar; // Fatal error: Readonly property Foo::$bar must have type
public static int $baz; // Fatal error: Readonly class Foo cannot declare static properties
}
扩展
与 readonly 属性一样,可以使用 readonly 类扩展 readonly 类。
readonly class A {}
readonly class B extends A {}
禁止用非只读类扩展只读类,反之亦然。
readonly class A {}
class B extends A {}
// Fatal error: Non-readonly class B cannot extend readonly class A
class A {}
readonly class B extends A {}
// Fatal error: Readonly class B cannot extend non-readonly class A
反射
ReflectionClass::isReadOnly()添加了一个方法来检查该类是否是只读的。
它还ReflectionClass::getModifiers()向方法ReflectionClass::IS_READONLY添加了一个标志。
向后不兼容的更改
没有不兼容的更改。
投票
投票时间为 2022/04/27 至 2022/05/11。
该 RFC 以 28 票赞成和 7 票反对的多数票被接受。
总结
只能分配一次,分配后不能更改。
简而言之,它是一个不可变的对象。
readonly class Foo{
public function __construct(
public int $bar
) {}
}
$foo = new Foo(1); // OK
$foo->bar = 2; // NG
readonly 的类不能设置静态属性,不能使用动态属性,需要指定类型,而且一旦设置的值不能重写,能做的就很有限了。
可以防止意外重写某处的值等事故,并且可以运行健壮且高度安全的实例。
PHP 9.0最终禁止访问未定义的属性,但 readonly 类几乎向上兼容。
本文为 @ 杜江(字洛逸) 创作并授权 21CTO 发布,未经许可,请勿转载。
内容授权事宜请您联系 webmaster@21cto.com或关注 21CTO 公众号。
该文观点仅代表作者本人,21CTO 平台仅提供信息存储空间服务。