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

Php 在什么情况下可能不继承父字段?,php,inheritance,Php,Inheritance,我今天有一只奇怪的虫子(骚扰我)。涉及三个继承级别: 爷爷: abstract class Zend_Db_Table_Row_Abstract implements ArrayAccess, IteratorAggregate { protected $_data = array(); /* snip */ } namespace Survey\Db\Table\Ro

我今天有一只奇怪的虫子(骚扰我)。涉及三个继承级别:

爷爷

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  
妈妈

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  
孩子

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  
异常

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行似乎不相关,但我添加它只是为了让您相信我;)

PHP5.4.11,PHP5.4.8不存在问题

当我看到for的时候,我想,这会解决问题,因为这个bug正是我看到的奇怪的意外结果

但事实证明,升级到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();
请一步一步地将代码最小化,以查看是否/何时出现问题(我想知道为什么您还没有这样做)

如果您确定这在PHP5.4.8上有效,而在PHP5.4.11上无效,那么您在PHP中发现了一个bug,应该在PHP.net上报告它

答案可能不一样(可能只是一路上“未设置”)。
最小化代码,您就会知道。

如果您不希望父字段通过对象在子类中继承,则将父字段定义为“静态”。

您是否可以为
$this->\u data
的引用添加多一点上下文。包括引用它的类和方法。正如您发布的代码所示,child应该可以访问成员变量,我想知道在通过SurveyItem进行扩展时是否需要为AbstractRow命名。我在5.3.20上尝试过这一点,使用空类(使父类和子类抽象以便编译),一切正常。在您当前的PHP版本上尝试一下,以确保它不是Zend中的某些东西(可能是一些PHP魔法)妨碍了您的工作?但是,如果它在早期版本5.4上工作,并且没有任何其他更改,那么它一定是一个PHP错误,可能是PHP的“魔力”。我正在努力改进这个问题,给你提供更多的上下文。好的,我想我开始理解它了,多亏了聊天中的新闻提要。我认为这是PHP中的一个bug,在某些情况下,magic _set()和_get()会被调用两次。第177行实际上发生在魔法方法的上下文中。升级到5.4.12并没有解决问题!