Tree/AlPrintAll
Материал из PhpWiki.
Деревья в базах данных => Списки смежности => Вывод дерева => Вывод всего дерева
Как вывести все дерево?
popoff
<?php //1. Загружаем данные. Загружаем в таком виде, в каком они записаны в таблице. $a_tree=array(); //Ключ массива - идентификатор родительского элемента // значение - список дочерних элементов //Загружаем сразу все дерево одним запросом $r=mysql_query(" select t_catalog_tree.k_item, #идентификатор элемента t_catalog_tree.k_parent, #идентификатор родительского элемента # элементы верхнего уровня содержат здесь 0 t_catalog.s_name #название from t_catalog, #данные t_catalog_tree #дерево where t_catalog.k_item=t_catalog_tree.k_item order by t_catalog.s_name"); //Обратите внимание, что в запросе строки отсортированы по s_name. //Это сделано для того, что бы и сами элементы массива $a_tree и // списки дочерних элементов этого массива были отсортированы по этому полю. for($i=0;$i<mysql_num_rows($r);$i++) { $f=mysql_fetch_assoc($r); if(empty($a_tree[$f['k_parent']])) $a_tree[$f['k_parent']]=array(); $a_tree[$f['k_parent']][]=$f; } //2. Выводим данные. // Поскольку глубина дерева у нас не ограничена, то логичнее всего // для вывода использовать рекурсивную функцию. // Если используемый Вами шаблонный движок это позволяет, то можно // использовать рекурсивный шаблон. //Обратите внимание на символ "&" перед аргументом $a_tree. //Я использовал его для того, что бы при каждом рекурсивном вызове // php не выделял новую память и не копировал туда весь массив $a_tree, // а только передавал ссылку на исходный массив. function tree_print(&$a_tree,$k_parent=0) { //условие завершения рекурсии //Условие, при котором функция никогда не вызывает сама себя //функция empty() - вернет ложь во всех нужных нам случаях: // - элемент массива не определен // - элемент массива определен, но является пустым массивом if(empty($a_tree[$k_parent])) return; echo "<ul>"; for($i=0;$i<count($a_tree[$k_parent]);$i++) { echo "<li>".$a_tree[$k_parent][$i]['s_name']; //рекурсивный вызов - список всех дочерних элементов нужно вставить // именно в этом месте: // <li>название // ''тут список дочерних элементов, он показывается рекурсивным вызовом'' // </li> tree_print($a_tree,$a_tree[$k_parent][$i]['k_item']); echo "</li>"; } echo "</ul>"; } //Показываем все дерево: tree_print($a_tree); ?>
Обратите внимание, что в приведенном мной примере вывод дерева никак не зависит от способа хранения дерева (толи это списки смежности, толи это вложенные множества, толи дерево хранится в базе ~MySQL, толи в MSSQL). Нам достаточно только сформировать правильный массив $a_tree и передать его аргументом функции tree_print().
Обратите так же внимание на то, что tree_print() не зависит не только от того, каким способом у нас хранится дерево, но и не зависит от того, какую часть дерева мы хотим вывести. Если мы хотим вывести не все дерево, а только его часть, то нам нужно сформировать массив $a_tree, в котором содержится только нужная нам часть дерева.
Именно из-за такой независимости функции вывода дерева, в нашем случае tree_print() от способа хранения, от используемой базы данных и от того, какую часть дерева мы хотим вывести, вопрос типа "как вывести все дочерние элементы" легко может сбить с толку. Что конкретно Вам не понятно? Вам не понятно, как сделать нужную Вам выборку и сформировать нужный массив или Вам не понятно, как устроена функция tree_print()? Когда Вы задаете вопрос, формулируйте его точно!