Good time of day.

Please tell me how to display in the template a category tree by levels from an array of objects (Doctrine)

Entity fields: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-self-referencing

/** * @var \Doctrine\Common\Collections\Collection * * @ORM\OneToMany(targetEntity="Application\Entity\Category", mappedBy="parent", cascade={"remove"}) */ private $children; /** * @var \Application\Entity\Category * * @ORM\ManyToOne(targetEntity="Application\Entity\Category", inversedBy="children") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="parent", referencedColumnName="id", nullable=true) * }) */ private $parent; 

In the table, everything is fine:

 id parent name 1 null Категория 1 2 null Категория 2 3 1 ПодКатегория 3 к 1 4 2 ПодКатегория 4 к 2 

If we go through foreach, then in each entry $ category-> getParent == null. (Perhaps due to the fact that this is not just a field, but a link to another record) If you make a selection as an array, then the Parent field is completely absent.

Zend Framework 3 Doctrine 2 PosrgreSQL

    2 answers 2

    It came to me that the Parent field is not just the id of the parent category, you can get child categories through the virtual field Сhildren. This is a huge plus, since even recursion is not needed here.

    Here is the solution:

     <?php foreach($categories as $category): ?> <?php if ($category->getParent() === null) : ?> <li><?= $category->getName() ?></li> <?php foreach($category->getChildren() as $children) {?> <li><?= $children->getName() ?></li> <?php }?> <?php endif; ?> <?php endforeach; ?> 

    Only increases the number of queries in the database ((

      In this solution, only 1 query to the database

       $categoryTree = []; foreach ($categories as $category) { $parentId = $category->getParent() ? (int)$category->getParent()->getId() : null; $categoryTree[$parentId][] = $category; } foreach ($categoryTree[null] as $root) { $root->getName(); if (isset($categoryTree[$root->getId()])) { foreach ($categoryTree[$root->getId()] as $child) { $child->getName(); } } }