如何禁用 php 对象的动态属性,让它们表现得像未定义的变量
通常,当您访问不存在的类的属性时,它对该类没有任何意义,并且很可能是拼写错误。使用不存在的普通变量会因此引发警告。
当然,在很多用例中,自动属性很有用,但我发现在一般情况下,它会导致许多不清楚和无声的错误,您需要在这些错误中发出警告或错误。
我找到了一种允许动态引发错误的方法,但它看起来相当复杂(也许我可以将其变成一个trait
)。此外,如果在解析/编译期间收到警告或错误,那就太好了。我大约 10 年前就已经看到过这个报道,从那以后有没有更好的方法来做到这一点(比如编译器开关或其他东西)?
请注意,密封班级在这里也没有帮助。
class Foo {
public $rowNumber;
public $modificationDate;
public $userName;
// seal the class for dynamic properties
public function __set($name, $value) {
die("Cannot set property '$name' to '$value', property does not exist\n");
}
public function __get($name) {
die("Cannot get value for property '$name', property does not exist\n");
}
}
$x = new Foo();
$x->rowNumber = 42;
$x->modDate = "2022-12-12"; // raises error with the __set function present, otherwise nothing happens
print_r($foo); // raises standard warning from PHP, which is helpful
print_r($x);
Usually, when you access a property of a class that doesn't exist, it has no meaning to that class and it is likely a typo. Using a normal variable that doesn't exist raises a warning for that reason.
Of course, there are plenty of use-cases where automatic properties are helpful, but I find that in the general case, it causes a lot of unclear and silent bugs, where you'd want a warning or error.
I found a way that allows an error to be raised dynamically, but it seems rather convoluted (maybe I can turn it into a trait
). Besides, it'd be nice to get a warning or error during parsing/compilation. I've seen this reported some 10 years ago already, is there a better way of doing this since (like a compiler switch or something)?
Note, sealing the class doesn't help here either.
class Foo {
public $rowNumber;
public $modificationDate;
public $userName;
// seal the class for dynamic properties
public function __set($name, $value) {
die("Cannot set property '$name' to '$value', property does not exist\n");
}
public function __get($name) {
die("Cannot get value for property '$name', property does not exist\n");
}
}
$x = new Foo();
$x->rowNumber = 42;
$x->modDate = "2022-12-12"; // raises error with the __set function present, otherwise nothing happens
print_r($foo); // raises standard warning from PHP, which is helpful
print_r($x);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
PHP 8.2(在提出这个问题后发布)不推荐使用动态属性。
我试图找出是什么触发了我的代码中的弃用错误(嵌套在特征深处),并根据您使用 __set 的建议解决了这个问题:
PHP 8.2 (released after this question was asked) deprecates dynamic properties.
I was trying to find what triggered the deprecation error in my code (nested deep in a trait), and solved that with your suggestion of using __set: