У меня есть Entity, который выглядит так:
class Privilege { /** * @Id @Column(type="bigint") * @GeneratedValue(strategy="AUTO") */ private $id; /** * @Column(type="string",length=255) */ private $name; /** * @Column(type="string",length=255) */ private $slug; /** * @OneToMany(targetEntity="Privilege", mappedBy="parent") */ private $children; /** * @ManyToOne(targetEntity="Privilege", inversedBy="children") * @JoinColumn(name="p_id", referencedColumnName="id") */ private $parent;
Если у Privilege Entity
нет родителя, поле NULL. У меня есть базовый запрос:
$qb = $this->em->createQueryBuilder() ->select('p') ->from('\Dashboard\Entity\Privilege', 'p') ->andWhere('p.parent IS NULL'); $q = $qb->getQuery(); $privileges = $q->getResult();
Я бы хотел, чтобы результат массива возвращался из этого метода, чтобы выглядеть примерно так:
root1: child1: subchild1a subchild2a child2: subchild1b subchild2b subchild3b subsubchild1b child3: subchild1c root2: .... ....
Есть ли способ получить данные из Doctrine 2, чтобы получить результаты массива таким образом? Если нет, как бы вы построили этот массив? Я все еще играю с Doctrine 2, и я заметил, что каждый элемент в моем массиве $privileges
имеет $privilege->getChildren()
который возвращает PersistentCollection
, а не фактическую запись.
Если мне нужно самостоятельно построить это вложенное дерево (т. Е. Не встроено в Doctrine), как мне заставить этот PersistentCollection
возвращать в фактические данные, чтобы я мог построить какой-то рекурсивный метод для его создания для меня? Я просматриваю документы, но, очевидно, не в том месте.
Результаты уже находятся в вложенном дереве. PersistentCollection
можно повторить так, как если бы это был массив:
foreach($parent->getChildren() as $child) { // $child is an instance of Privilige }
Тем не менее вы должны попробовать $privileges = $q->getArrayResult();
и посмотрите, дает ли это результат, который вы предпочтете.
Я думаю, что то, что вы ищете, называется «ассоциация с одиночными именами « один-ко-многим »в документации: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association- mapping.html # один-к-одному-автореферентно
Вот код иерархии категорий из документов:
<?php /** @Entity **/ class Category { // ... /** * @OneToMany(targetEntity="Category", mappedBy="parent") **/ private $children; /** * @ManyToOne(targetEntity="Category", inversedBy="children") * @JoinColumn(name="parent_id", referencedColumnName="id") **/ private $parent; // ... public function __construct() { $this->children = new \Doctrine\Common\Collections\ArrayCollection(); } }
«Это эффективно моделирует иерархию категорий и с точки зрения базы данных, называется подходом списка смежности».
Поэтому я думаю, что это должно сделать всю работу за вас и создать иерархию массивов, в которой вы нуждаетесь.
Поскольку у вас уже есть ваши аннотации, например, в документах, ваш $parent->getChildren()
уже должен содержать всю иерархию, как сказал @rojoca.