在什么情况下父字段可能不被继承


Under what circumstances is it possible that parent fields are not inherited?

我今天遇到了一个奇怪的bug。涉及三个继承级别:

爷爷

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 */
}

异常

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 不存在问题

当我看到为未设置的受保护属性调用两次的错误#63462 Magic方法的修复时,我想,这将解决问题,因为这个错误会导致我看到的奇怪的意外结果。

但事实证明,问题在更新到PHP5.4.12后仍然存在。PHP中出现另一个类似错误的可能性似乎很高。

问题:

我得到的信息是,爷爷中定义的受保护字段在孩子中没有定义。什么情况会导致这样的结果?

以下代码段在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 上报告

答案可能会有所不同(也许只是一路上"未设置")。尽量减少你的代码,你就会知道。

如果不希望父字段通过对象在子类中继承,则将父字段声明为"static"。