I think that most of all you can get to Page require Book as one of the constructor arguments and add it to this copy of the book. That way, you never float around Page , but they are always associated with some book (although it is still possible to have the same Page in many Book s.
class Book { public function addPage($page) { if(is_a($page,'Page') { $this->pages->push($page); } else if (is_string($page)) { new Page($this,$page) } else { throw new InvalidArgumentException("Expected string or 'Page' - ".gettype($page)." was given instead"); } } } class Page { public function __construct(Book $book, $pagename) { $book->addPage($this); } }
It looks ugly though ...: /
source share