При каких обстоятельствах возможно, что родительские поля не наследуются?

Сегодня у меня есть любопытная ошибка (прослушивание). Существует три уровня наследования:

дедушка

abstract class Zend_Db_Table_Row_Abstract implements ArrayAccess, 
                                                     IteratorAggregate
{
    protected $_data = array();

    /* snip */
}

Мама

namespace Survey\Db\Table\Row;

class AbstractRow extends \Zend_Db_Table_Row_Abstract
{
    /* snip */
}

Ребенок

namespace Survey\Db\Table\Row;

class SurveyItem extends AbstractRow implements ISkippable
{
    /* snip */
}

Exception

Type:     ErrorException  
Value:    Undefined property: Survey\Db\Table\Row\SurveyItem::$_data  
Location: [...]/Zend/Db/Table/Row/Abstract.php in handleError , line 177  

Строка 177 не кажется актуальной, но я добавляю ее просто так, чтобы вы мне поверили;)

if (!array_key_exists($columnName, $this->_data)) {

PHP 5.4.11, проблема не существовала с PHP 5.4.8

Когда я увидел fix для Ошибка # 63462 Магические методы, называемые дважды для устранения защищенных свойств, подумал я, что решение проблемы разрешилось, поскольку эта ошибка приводит к точному неожиданному неожиданному результату, который я видел.

Но, оказывается, проблема сохраняется после обновления до PHP 5.4.12. Вероятность того, что есть еще одна подобная ошибка в PHP, кажется довольно высокой.

Вопрос:

Я получаю информацию о том, что защищенным полем, определенным в дедушке, является undefined в Ребенке. Какие сценарии могут привести к такому результату?

Ответ 1

Следующий фрагмент работает безупречно на PHP 5.4.9:

class A
{
    protected $foo = 'hello';
    public function bar()
    {
        echo $this->foo;
    }
}

class B extends A {}

class C extends B {}

$c = new C();
$c->bar();

Пожалуйста, сводите к минимуму ваш код шаг за шагом, чтобы увидеть, если/когда возникает проблема (интересно, почему вы еще не сделали этого)

Если вы уверены, что это сработало на PHP 5.4.8 и не работает на PHP 5.4.11, то вы обнаружили ошибку в PHP и должны сообщать об этом на php.net

Ответ может быть другим (может быть, он просто получил "unset" по пути). Минимизируйте свой код, и вы узнаете.

Ответ 2

Если вы не хотите, чтобы родительское поле наследовалось в дочернем классе через объект, объявите родительское поле как "статическое".