如何在PHP中访问父对象的类变量?

时间:2020-03-05 18:53:16  来源:igfitidea点击:

类A的实例实例化了几个其他对象,例如来自类B的实例:

$foo = new B();

我想从B中的方法访问A的公共类变量。

除非我缺少任何东西,否则执行此操作的唯一方法是将当前对象传递给B的实例:

$foo = new B($this);

这是最佳实践还是还有另一种方法?

解决方案

回答

我将首先检查我们是否使用了错误的模式:根据应用程序逻辑,B真的应该了解A吗?如果B需要了解A,那么亲子关系似乎还不够。例如,A可以是孩子,或者A的逻辑的一部分可以进入层次结构中"在" B之下的第三对象(即,不知道B)。

就是说,我建议我们在B中有一个方法将A注册为数据源,或者在A中创建一个方法将B注册为观察者,并在B中创建一种匹配方法,A用来将值的更改通知B。

回答

在我看来,这很好,我倾向于使用"有人会保持这种理解吗?"的经验法则。这是一个易于理解的解决方案。

如果只有一个" A",则可以考虑使用注册表模式,例如,请参见http://www.phppatterns.com/docs/design/the_registry

回答

与Paul所说的相似,如果只有一个A,则可以将其实现为单例。然后,我们可以使用setter方法(实质上是再次聚合)将A的实例作为参数传递给构造函数(聚合),也可以直接在构造函数(组合)中设置此关系。

但是,尽管单例功能强大,但请谨慎使用组合实现它们。认为可以这样做并摆脱构造函数参数很高兴,但这也使得在没有代码重写的情况下无法用其他方法替换A。永久地,即使使用单例,我也会坚持聚合

$foo = new B( A::getInstance() );

回答

$foo = new B($this);

不幸的是,这样的代码不符合我的需求。还有其他方法可以访问父对象属性吗?

我将尽力解释原因。我们编写了一个游戏软件,某些类具有非常"异常"的依赖关系,并以不同的方式相互影响。这就是为什么有时在每个实例中都没有链接到父母的情况下代码几乎变得不被支持的原因(有时甚至来自不同上下文的几个父母,也就是小队可能属于Battle和User等)。

现在,链接为什么不令我满意的原因。当我为客户端生成输出时,我使用一种XML序列化对象。直到遇到递归引用(如与父母的链接)之前,它都非常好用。我可以使它们受到保护,但随后它们就会松散使用,即(虚拟示例)

$this->squad->battle->getTeam($tid)->getSquad($sqid)->damageCreature(...);

在每个可序列化类中实现序列化方法并在序列化器内部调用的另一种方式是这样的:

$obj->toXML($node);
$this->appendChild($node);

但这是很多需要编写和支持的东西!有时我会动态生成用于序列化程序的对象(较少的流量)。

我什至想到了一个hack:"教"序列化器忽略某些类中的某些属性))。嗯...好主意...

这是一个漫长的讨论,但请相信我,注册表和观察员不适合。还有其他想法吗?