dllweb
@dllweb

Массивы деревья на php почему исчезает дерево?

Никак не могу понять, почему рушится дерево, в проекте симфони делаю так:
Есть сервис который отвечает за сортировку по ключам родителей в массиве

public function persistviewtree($arr){
        return $this->viewtree($arr, 0);
    }


    public function viewtree($arr, $root){

        if(is_array($arr) and isset($arr[$root])){


            $str = "<ul>";

                    foreach ($arr[$root] as $r) {
                    $str .= "<li data-node=".$r['id']." style=\"position:relative;\" class=\"list-group-item\">
                    <a href=\"/wikiedit/".$r['id']."\">".$r['name']."</a>
                    <i class=\"glyphicon glyphicon-remove pull-right\" style=\"cursor:pointer;\" onclick=\"R.wiki.delete(".$r['id'].");\</i>";              
                    $str .= $this->viewtree($arr, $r['id']);
                    $str .= "</li>";
                    }

            $str .= "</ul>";

        } else {

            return false;

        }

        return $str;

    }


Есть массив вида

CN11YiEWxgg.jpg

вызов функции persistviewtree происходит в контроллере
оттуда уже обычной переменной отдаётся в шаблон.

В примечание скажу что, если в первой ячейке представленного массива ключ 0
то всё работает правильно, если же так как сейчас на картинке, то дерево отображается или частично, или совсем пропадает.

Если тот же эксперимент повторить в процедурной среде, то всё работает вообще без проблем.
  • Вопрос задан
  • 2555 просмотров
Пригласить эксперта
Ответы на вопрос 2
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
вызов функции persistviewtree происходит в контроллере

фуфуфу. Лучше вынесите это хотя бы к хелпер для twig.

В целом же ваш алгоритм должен работать корректно и ничего не должно зависеть от порядка нод. Оформите нерабочий пример на каком ideone.com - ибо так по коду проблема явно не в нем.
Ответ написан
lexxpavlov
@lexxpavlov
Программист, преподаватель
Вывод подобных массивов - задача для Twig. Это делается простейшим способом:
{% extends '::layout.html.twig'%}

{% block content %}
<ul>
{% for items in tree %}
{% for item in items %}
    <li data-node="{{ item.id }}" style="position:relative;" class="list-group-item">
         <a href="/wikiedit/{{ item.id }}">{{ item.name }}</a>
         <i class="glyphicon glyphicon-remove pull-right" style="cursor:pointer;" onclick="R.wiki.delete({{ item.id }});"></i>
    </li>
{% endfor %}
{% endfor %}
</ul>
{% endblock %}

Это если нет вложенных элементов. Если есть вложенные, то нужно сделать отдельный шаблон (без extends), и тут его вызывать через include.

А у вас есть ещё ошибка в выводе - метод $str .= $this->viewtree($arr, $r['id']); вызывается сначала для массивов первой вложенности, а у них нет ключа id. Тут нужно сделать два разных метода - один будет обрабатывать первый уровень вложенности, а второй метод - сами элементы с данными.
И если у вас нет вложенных друг в друга элементов с данными, то рекурсию использовать не стоит. У вас же явно видно, что элементы разных уровней вложенности имеют разный формат данных, значит, обрабатывать их одним методом некорректно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы