Вызвать __get() для защищенных свойств с оператором -›?

Моя команда использует методы ленивой загрузки для загрузки подобъектов из нашей базы данных. Для этого мы используем волшебный метод __get() и делаем вызов базы данных. Все наши свойства защищены, поэтому метод __get вызывается извне объекта, но наша проблема в том, что он не вызывается из объекта без использования $this->__get($name);

Итак, мой вопрос: можно ли заставить __get() вызываться с обычным оператором цепочки даже изнутри объекта?

Если я хочу связать доступ к объекту, мне сейчас нужно сделать:

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

Можно ли написать следующее, но при этом вызывать __get()?

$this->subObject->subObject->subObject

Спасибо, Джордан


person Jordan    schedule 22.03.2013    source источник


Ответы (2)


Иордания,

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

person Robert K    schedule 22.03.2013

@Robert K Или (например):

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, который возвращает объект.

person mkjasinski    schedule 22.03.2013