Подтвердить что ты не робот

PHP класс Child Magic __isset работает, но __get не

У меня есть абстрактный родительский класс Mongo_Document (из mongodb-php-odm) и унаследованный класс Model_ActionPlan. Mongo_Document имеет магические методы __isset и __get, которые взаимодействуют с массивом внутри класса Mongo_Document.

Я пытаюсь использовать следующий код (фрагмент изнутри метода Model_ActionPlan):

if (isset($this->status))
{
    if (($this->status === "closed") AND ($this->close_type != "failure"))
    {
        return;
    }
}

(Обратите внимание, что close_type гарантированно устанавливается, если status == 'closed'.)

Вызов isset возвращает true, а затем выполнение переходит к следующему оператору. Там я получаю следующую ошибку:

 Undefined property: Model_ActionPlan::$status

Однако, если я заменил $this->status на parent::__get('status'), этот код работает так, как ожидалось. Обратите внимание, что всюду в программе я могу использовать:

$ap = new Model_ActionPlan($plan_id);
echo $ap->status;
// Prints 'closed' (or 'active') as expected

Только внутри самого класса это не работает.

Я огляделся, и я не могу найти нигде, где говорится, что магические методы нельзя вызвать в дочернем классе. Я мог бы использовать вызов parent::__get, но я думаю, что это, вероятно, неправильный способ сделать это. Кто-нибудь знает, есть ли правильный/лучший способ сделать это?

Обновлено # 1 2012-12-16: Полный код родительского класса здесь, на Github.

Обновлено # 2 2012-12-18: Для людей, которые задавали вопрос о том, где и где он установлен правильно, ответ заключается в том, что, поскольку вызов parent::__get('status') работает, проблема явно не в том, что переменная не получает значение. __get() получает свои данные из частной переменной instace, называемой _object. Если я var_dump($this), я вижу, что $this->_object['status'] соответствует ожидаемому "закрытому" значению.

Обновление # 3: Код дочернего класса доступен в https://gist.github.com/4332062. Важная часть начинается в строке 69.


Я видел этот похожий вопрос, но он говорит об использовании родительского метода магии, чтобы получить дочерние свойства, и моя проблема заключается в использовании родительского getter для получения родительского свойства.

4b9b3361

Ответ 1

Функция __get в родительском объекте несколько сложна, поэтому я не полностью понял, может ли происходить следующее: нет. Если ваша функция __get, однажды вызванная, каким-то образом инициирует другой вызов обратно в себя (возможно, с некоторыми промежуточными вызовами других функций в стеке), это именно то, что произойдет.

См. http://php.net/manual/en/language.oop5.overloading.php#55486, который показывает, что тот же самый тип ошибки регистрируется, когда геттер запускает вызов самому себе. В этом случае это довольно легко заметить, но с более сложным графиком вызовов чего-то вроде func() от __get() до funcB() до funcC() до __get() было бы непросто обнаружить.

Ответ 2

Не уверен, что я прав, но не следует использовать

$this->_object['status'] 

вместо

$this->status