Деревья в PHP + Twig 2.0

Предположим, есть задачка, вывести дерево.

Под рукой PHP, а как view — Twig.

Пусть структура данных на backend будет такой:

$tree = [

            [
                'name' => 'foo',
                'children' => [
                    [
                        'name' => 'bar',
                        'children' => [
                            [
                                'name' => 'baz',
                                'children' => [

                                ],
                            ],

                            [
                                'name' => 'baz',
                                'children' => [

                                ],
                            ],


                        ]
                    ]
                ]
            ]

        ];

Тогда простроить дерево можно так:

{% macro makeTree(node) %}
    {% import _self as self %}
    <li>
        <a href="#">{{ node.name }}</a>

        {% if node.children|length %}
            <ul>
                {% for child in node.children %}
                    {{ self.makeTree(child) }}
                {% endfor %}
            </ul>
        {% endif %}
    </li>
{% endmacro %}

{% from _self import makeTree %}

    {% if tree %}
        <div class="tree">
            <ul>
                {% for node in tree %}
                    {{ makeTree(node) }}
                {% endfor %}
            </ul>
        </div>
    {% endif %}

Получится вложенный список из ul и li.

Flat array to nested in php

Requirements = PHP 5.3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function buildTree($flat, $pidKey, $idKey = null)
        {
            $grouped = array();
            foreach ($flat as $sub){
                $grouped[$sub[$pidKey]][] = $sub;
            }
 
            $fnBuilder = function($siblings) use (&$fnBuilder, $grouped, $idKey) {
                foreach ($siblings as $k => $sibling) {
                    $id = $sibling[$idKey];
                    if(isset($grouped[$id])) {
                        $sibling['children'] = $fnBuilder($grouped[$id]);
                    }
                    $siblings[$k] = $sibling;
                }
 
                return $siblings;
            };
 
            $tree = $fnBuilder($grouped[0]);
 
            return $tree;
        }
function buildTree($flat, $pidKey, $idKey = null)
        {
            $grouped = array();
            foreach ($flat as $sub){
                $grouped[$sub[$pidKey]][] = $sub;
            }

            $fnBuilder = function($siblings) use (&$fnBuilder, $grouped, $idKey) {
                foreach ($siblings as $k => $sibling) {
                    $id = $sibling[$idKey];
                    if(isset($grouped[$id])) {
                        $sibling['children'] = $fnBuilder($grouped[$id]);
                    }
                    $siblings[$k] = $sibling;
                }

                return $siblings;
            };

            $tree = $fnBuilder($grouped[0]);

            return $tree;
        }

Usage:

1
2
3
4
5
6
7
8
9
$flat = array(
    array('id'=>100, 'parentID'=>0, 'name'=>'a'),
    array('id'=>101, 'parentID'=>100, 'name'=>'a'),
    array('id'=>102, 'parentID'=>101, 'name'=>'a'),
    array('id'=>103, 'parentID'=>101, 'name'=>'a'),
);
 
$tree = buildTree($flat, 'parentID', 'id');
print_r($tree);
$flat = array(
    array('id'=>100, 'parentID'=>0, 'name'=>'a'),
    array('id'=>101, 'parentID'=>100, 'name'=>'a'),
    array('id'=>102, 'parentID'=>101, 'name'=>'a'),
    array('id'=>103, 'parentID'=>101, 'name'=>'a'),
);

$tree = buildTree($flat, 'parentID', 'id');
print_r($tree);

Thanks! http://stackoverflow.com/a/27360654/1886270