在PHP类中,有可能动态地设置和检索未被声明的类属性。这些属性不遵守特定的(类似于类型化的属性),它需要使用__get()和__set()魔法方法来有效地防止或控制动态属性的设置和检索方式。
class User {
private int $uid;
}
$user = new User();
$user->name = 'Foo';
在上面的片段中,User类没有声明一个名称为name的属性,但由于允许动态属性,PHP允许设置它。
虽然动态属性提供了创建类的灵活性,如没有严格的类声明的价值对象,但它为应用程序中潜在的错误和意外行为提供了可能性。例如,由于PHP默许所有的动态属性,设置属性的语句中的一个错别字可能会被忽略。
在 PHP 8.2 及以后的版本中,为未声明的类属性设置一个值是被废弃的,并且在应用程序执行过程中第一次设置该属性时,会发出废弃通知。
class User {
private int $uid;
}
$user = new User();
$user->name = 'Foo';
Deprecated: Creation of dynamic property User::$name is deprecated in ... on line ...
从类中设置属性也会发出废弃通知:
class User {
public function __construct() {
$this->name = 'test';
}
}
new User();
Deprecated: Creation of dynamic property User::$name is deprecated in ... on line ...
动态属性有合法的用例,比如从动态JSON响应中得到的值对象,或者允许任意值的配置对象。
理想情况下,类应该在类中声明动态属性以避免废弃通知。不需要用一个属性类型来声明该属性。
豁免的动态属性模式
这种废弃有三种例外情况。使用下面的方法之一可以避免废弃的通知。
- Classes with
#[AllowDynamicProperties]
attribute. stdClass
and its sub-classes- Classes with
__get
and__set
magic methods
参考: https://php.watch/versions/8.2/dynamic-properties-deprecated#exempt