如何禁用 php 对象的动态属性,让它们表现得像未定义的变量

发布于 2025-01-16 20:34:20 字数 1021 浏览 1 评论 0原文

通常,当您访问不存在的类的属性时,它对该类没有任何意义,并且很可能是拼写错误。使用不存在的普通变量会因此引发警告。

当然,在很多用例中,自动属性很有用,但我发现在一般情况下,它会导致许多不清楚和无声的错误,您需要在这些错误中发出警告或错误。

我找到了一种允许动态引发错误的方法,但它看起来相当复杂(也许我可以将其变成一个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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

姜生凉生 2025-01-23 20:34:20

PHP 8.2(在提出这个问题后发布)不推荐使用动态属性。

我试图找出是什么触发了我的代码中的弃用错误(嵌套在特征深处),并根据您使用 __set 的建议解决了这个问题:

public function __set($property, $value) {
    assert(false, $property . " does not exist.");
}

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:

public function __set($property, $value) {
    assert(false, $property . " does not exist.");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文