ツリーに無制限のレベルがある場合は、再帰を使用する必要があります。また、ツリーに多数の項目がある場合は、ツリーを構築およびレンダリングするときにメモリ使用量を考慮する必要があります。
それを念頭に置いて、最近、次のパターンで同様の問題を解決しました。ツリーをロードしてから、ツリーをレンダリングします。
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 を使用して、必要に応じてクライアントにデータをロードする必要があります。データとレンダリング メソッドにパラメーターを追加して、要求に応じてツリーの特定のブランチに読み込むことができます。