当对象具有循环引用时,他们说这不是一个好主意。让我们看一个复合的例子:
class Book
{
private $title;
public function __construct($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
}
class Shelf
{
private $books = [];
public function addBook (Book $book)
{
$this->books[] = $book;
}
}
$shelf = new Shelf();
$sehlf->add (new Book('a'));
$sehlf->add (new Book('b'));
$sehlf->add (new Book('c'));
到目前为止一切顺利。出于某种原因,Book
必须知道Shelf
,所以我重写:
class Book
{
private $title;
private $shelf;
public function __construct($title, $shelf)
{
$this->shelf = $shelf;
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
}
class Shelf
{
private $books = [];
public function addBook (Book $book)
{
$this->books[] = $book;
}
}
$shelf = new Shelf();
$sehlf->add (new Book('a', $shelf));
$sehlf->add (new Book('b', $shelf));
$sehlf->add (new Book('c', $shelf));
他们说不好。
答案 0 :(得分:2)
循环引用存在一些问题,可能是found here,但我必须接受以上不是一个非常有问题的例子 - 因为很明显,必须先在书籍之前创建书架。
例如,最常见的问题之一是,如果假设变量是公共的,那么在print_r
的实例上使用Book
可能是“不可能的” - 会导致内存耗尽。
有几种方法可以解决循环引用问题,其中一种最常见的问题包括使用Setter injection。 e.g。
public function setShelf(Shelf $shelf)
{
$this->shelf = $shelf;
}
PHP特有的另一个问题是它可能有解决循环依赖的问题。请参阅this for example。
class Node {
public $parentNode;
public $childNodes = array();
function Node() {
$this->nodeValue = str_repeat('0123456789', 128);
}
function destroy()
{
$this->parentNode = null;
$this->childNodes = array();
}
}
function createRelationship() {
$parent = new Node();
$child = new Node();
$parent->childNodes[] = $child;
$child->parentNode = $parent;
$parent->destroy();
}
PHP将最终分配大约35MB的内存,没有充分的理由。要解决这个问题,我们可以使用析构函数,以便垃圾收集器知道如何在完成对象后处理对象。
function destroy()
{
$this->parentNode = null;
$this->childNodes = array();
}