如果属性不存在则默认为默认 getter 行为

发布于 2024-10-21 07:20:18 字数 1215 浏览 2 评论 0原文

我目前需要扩展一个类以向其添加功能(我无权访问基类来修改它),并且我遇到了一个问题。

基本上,我需要神奇的 getter 函数来返回一组私有变量(如果需要),但否则默认为默认行为。我需要这些属性是私有的,以便使用魔术设置器功能自动同步一些数据。

也就是说,这里有一些示例代码:

class newClass extends baseClass {
    private $private1;
    private $private2;

    ...

    public function __get($name) {
        if($name == 'private1') return $this->private1;
        if($name == 'private2') return $this->private2;
        ... (and so on)
        // and here, it should default back to it's default behavior (throwing
        // an error on getting invalid/inaccessable property, etc.)
        // I cannot just use property_exists, because there may or may not be
        // private variables in the base class that should not be exposed.
    }
    public function __set($name,$val) {
        // I use this to do some automatic syncing when the two private variables
        // above are set. This needs to be triggered, hence the private variables
        // in the first place.
    }
}

我知道,我可以使用 getProperty/setProperty 函数,但我希望它尽可能保持直观,尽管有人认为执行此类操作是违反直觉的。这两个私有财产彼此之间有密切的联系。当其中之一被设置时,从逻辑上讲,它会影响其他的。

截至目前,这是我能想到的避免 getter/setter 函数并保持属性之间紧密结合的同步的唯一合乎逻辑的方法。如果你们能想到其他可行的解决方案,请随时提出建议:)

I'm currently needing to extend a class to add functionality to it (I do not have access to the base class to modify it), and I'm running into an isssue with it.

Basically, I need the magic getter function to return a set of private variables if they are requested, but otherwise default to the default behaviour. I need these properties to be private so as to use the magic setter function to automatically sync some data.

That said, here's some example code:

class newClass extends baseClass {
    private $private1;
    private $private2;

    ...

    public function __get($name) {
        if($name == 'private1') return $this->private1;
        if($name == 'private2') return $this->private2;
        ... (and so on)
        // and here, it should default back to it's default behavior (throwing
        // an error on getting invalid/inaccessable property, etc.)
        // I cannot just use property_exists, because there may or may not be
        // private variables in the base class that should not be exposed.
    }
    public function __set($name,$val) {
        // I use this to do some automatic syncing when the two private variables
        // above are set. This needs to be triggered, hence the private variables
        // in the first place.
    }
}

I know, I could use getProperty/setProperty functions, but I would like this to remain as intuitive as possible, despite the argument that performing such operations is counter-intuitive. The two private properties are very much connected to each other. When one of them is set, it is logically going to affect the others.

As of right now, this is the only logical way I can think of to avoid getter/setter functions and maintain the closely bonded sync between properties. If you guys can think of anything else that may be a viable solution, feel free to suggest options :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

拧巴小姐 2024-10-28 07:20:18

PHP 没有像其他语言那样内置属性,__get 和 __set 确实是您应该在这里使用的。但因此需要完成更多的工作。

您的问题似乎是最重要的 property_exists 。从类内部确定属性的公开性并不容易(除非进行内省)。但是您至少可以使用 get_object_vars 过滤掉基类中的私有变量:

 function __get($name) {
     static $r; if (!isset($r)) { $r = new ReflectionClass($this); }

     if (($p = $r->getProperty($name)) and $p->isPublic()) {
         return $this->$name;
     }
     elseif (method_exists($this, "get_$name")) {
         return $this->{"get_$name"}();
     }
     else trigger_error("inaccessible property ->$name", E_USER_NOTICE);
 }

为了恢复默认行为,您能做的最好的事情就是手动输出错误消息。

PHP does not have a property builtin like other languages, __get and __set are indeed what you should use here. But it's a bit more work to accomplish therefore.

Your problem seems to be property_exists foremost. It's not easily possible to determine the publicity of properties from within the class (except with introspection). But you can use get_object_vars to filter out private variables from the base class at least:

 function __get($name) {
     static $r; if (!isset($r)) { $r = new ReflectionClass($this); }

     if (($p = $r->getProperty($name)) and $p->isPublic()) {
         return $this->$name;
     }
     elseif (method_exists($this, "get_$name")) {
         return $this->{"get_$name"}();
     }
     else trigger_error("inaccessible property ->$name", E_USER_NOTICE);
 }

For reverting back to default behaviour the best you can do is to manually output an error message.

养猫人 2024-10-28 07:20:18

不要这样做,使用 getter/setter。它们的工作量与您在这里所做的工作量完全相同。

Don't do this, use getter/setters. They are exactly the same amount of work as what you are doing here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文