Вам нужно будет использовать рекурсию, если ваше дерево будет иметь неограниченные уровни, и если у вас будет много элементов в дереве, вам нужно будет учитывать использование памяти при создании и рендеринге дерева.
Помня об этом, я недавно решил проблему аналогичного типа с помощью следующего шаблона: загрузите дерево, а затем обработайте дерево.
Начиная с метода render(), вы получите все данные для загруженного дерева. Вы начнете с родительских узлов и получите родительских детей. get_children() имеет рекурсивный вариант для получения детей детей. Как только данные будут загружены, затем визуализируйте данные. Начните с рендеринга узлов верхнего уровня, а затем рекурсивно для детей и детей.
Вам нужно заполнить части фактически захватить данные из источника данных, но вот начало:
<?php
class Tree
{
var $tree = array();
function render()
{
$this->tree = $this->load();
$html = ''; // use your favorite templating system to generate the html
foreach ($this->tree as $parent_node)
{
$html .= $this->render_node($parent_node);
}
return $html;
}
function render_node($parent_node,$recursive=true)
{
// use your favorite templating system to generate the html
$html = '<ul><li>' . $parent_node->name;
$html .= '<ul>';
foreach ($parent_node->children as $child)
{
$html .= '<li>' . $child->name;
if ($recursive === true)
{
$html .= $this->render_node($child,$recursive);
}
$html .= '</li>';
}
$html .= '</ul>';
$html .= '</li></ul>';
return $html;
}
function load_tree()
{
$parents = $this->get_tree_parents();
foreach ($parents as $parent)
{
$parent->children = $this->get_children($parent);
}
$this->tree = $parents;
}
function get_tree_parents()
{
// find all top level nodes in the tree
return $parent_nodes;
}
function get_children($parent,$recursive=true)
{
// find all child nodes of the $parent
$children = array(/*...*/);
if ($recursive === true)
{
foreach ($children as $child)
{
$child->children = $this->get_children($child,$recursive);
}
}
return $children;
}
}
И запустить что-то вроде этого, вы бы просто нужно:
<?php
$tree = new Tree();
echo $tree->render();
Есть все виды оптимизаций, которые вы можете сделать в зависимости от вашего конкретного варианта использования. Если у вас огромное дерево, вам, вероятно, понадобится использовать ajax для загрузки данных на клиент по мере необходимости. Вы можете добавлять параметры к методам данных и рендеринга для загрузки по определенным ветвям дерева по запросу.
Эта ссылка может помочь: http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html – jeff
У меня есть идея о том, как хранить данные, но я не могу думать о том, как ее восстановить позже иерархия, вы знаете? – ranisalt
@jeff: Хорошая ссылка. – mshsayem