使用 - >在受保护的属性上调用__get()运营商?

时间:2013-03-22 15:36:40

标签: php magic-methods lazy-loading

我的团队正在使用延迟加载技术从我们的数据库加载子对象。为此,我们使用magic __get()方法并进行数据库调用。我们所有的属性都受到保护,因此从对象外部调用__get方法,但我们的问题是它不会在不使用$this->__get($name);的情况下从对象内调用

所以我的问题是:是否可以强制使用普通链接运算符调用__get(),甚至可以从对象内部调用?

如果我想链接对象访问,我目前必须这样做:

$this->__get('subObject')->__get('subObject')->__get('subObject') 

是否可以编写以下内容,但仍然可以调用__get()?

$this->subObject->subObject->subObject

谢谢, 约旦

2 个答案:

答案 0 :(得分:1)

约旦,

PHP不会调用__get()方法,除非该属性不可访问 - 因为它不存在,或者因为可见性。当从调用范围隐藏属性时,将调用__get()方法,因为该属性不可访问。当引用该属性并且调用范围可用时,__ get()将从不触发。 (这并不意味着为现有/可访问的财产开火。)

要解决此问题,您必须重命名内部属性。使用名称,下划线为它们添加前缀,或者将它们存储在具有特殊名称的公共数组参数中。以下是有点人为的,但它应该证明你如何处理这种情况。

class MyObject {
   protected $lazyloads = array();

   protected function lazyload($relation) {
     // ...
   }

   public function __get($key) {
     if (isset($this->lazyloads[$key]) {
       return $this->lazyloads[$key];
     } else {
       return $this->lazyload($key);
     }
   }
}

请参阅:http://www.php.net/manual/language.oop5.overloading.php#object.get

答案 1 :(得分:0)

@Robert K Or(例如):

class A
{
    protected $objects = array();

    public function __get($name)
    {
        if(isset($this->objects[$name])) {
            return $this->objects[$name];
        }
        return null; // or throw \Exception
    }
}
class B
{
    protected $objects = array();

    public function __get($name)
    {
        // for example: $this->objects[$name] is type of A
        if(isset($this->objects[$name])) {
            return $this->objects[$name];
        }
        return null; // or throw \Exception
    }
}

每个返回的对象必须有一个返回对象的魔术方法__get