При каких обстоятельствах возможно, что родительские поля не наследуются?
Сегодня у меня есть любопытная ошибка (прослушивание). Существует три уровня наследования:
дедушка
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
Если вы не хотите, чтобы родительское поле наследовалось в дочернем классе через объект, объявите родительское поле как "статическое".