最近,在尝试不同的依赖注入方法时,我偶然发现了一个概念,我可能会有相互引用的类。
这可能非常有用,我想在尝试从视图,模型或控制器对象访问数据库对象时,例如。
但是如果有任何陷阱我只是徘徊?
像内存泄漏等等。
对不起,如果这似乎是一个愚蠢的问题,但无论如何这个想法对我来说都是新的。
class foo{
public $bar;
}
class bar{
public $foo;
public function __construct($foo) {
$this->foo=$foo;
$this->foo->bar=$this;
}
}
$foo = new foo;
$bar = new bar($foo);
var_dump($foo->bar->foo->bar->foo->bar->foo);
// object(foo)#1 (1) {
// ["bar"]=>
// object(bar)#5 (1) {
// ["foo"]=>
// *RECURSION*
// }
// }
答案 0 :(得分:1)
它是任何语言的代码味道。应不惜一切代价避免循环依赖。解决方案通常是将共享依赖项抽象为一个不依赖于任何东西的公共类。
答案 1 :(得分:1)
你给出的例子有点人为,但一般来说,让类实例相互引用是完全有效的。
例如,如果你开发一个解析器,那么当你构建解析树时,有很多这样的情况。
要详细说明一下,请考虑从用PHP编写的Nikic优秀PHP解析器中提取的以下类: https://github.com/nikic/PHP-Parser
您会看到PHPParser_Node_Expr_Array
的一个实例,它显然可以在PHPParser_Node_Expr
字段array
字段中显示在其他PHPParser_Node_Expr
个实例中。
<?php
/**
* @property PHPParser_Node_Expr_ArrayItem[] $items Items
*/
class PHPParser_Node_Expr_Array extends PHPParser_Node_Expr
{
/**
* Constructs an array node.
*
* @param PHPParser_Node_Expr_ArrayItem[] $items Items of the array
* @param int $line Line
* @param null|string $docComment Nearest doc comment
*/
public function __construct(array $items = array(), $line = -1, $docComment = null) {
parent::__construct(
array(
'items' => $items
),
$line, $docComment
);
}
}
答案 2 :(得分:0)
PHP 5.3之前的PHP垃圾收集器无法解析循环引用,因此无法为这些对象和整个连接的对象图释放已分配的内存。
现在问题已解决:http://php.net/manual/en/features.gc.collecting-cycles.php
确保始终尽量避免使代码过于复杂。