将修改后的预订树遍历模型(嵌套集)转换为

时间:2021-06-03 16:39:41

I am trying to get my data which is hierarchically set up with a tree traversal model into an < ul> in order to show on my site.

我试图将我的数据分层设置为树遍历模型到

    ,以便在我的网站上显示。

Here is my code:

这是我的代码:

function getCats($) {
  // retrieve all children of $parent
  $query = "SELECT max(rght) as max from t_categories";
  $row = C_DB::fetchSingleRow($query);
  $max = $row["max"];
  $result ="<ul>";
  $query = "SELECT * from t_categories where lft >=0 and rght <= $max";
  if($rs = C_DB::fetchRecordset($query)){
    $p_right ="";
    $p_left ="";
    $p_diff="";          
    while($row = C_DB::fetchRow($rs)){
      $diff = $row["rght"] -$row["lft"];

      if($diff == $p_diff){
        $result.= "<li>".$row['title']."</li>";
      }elseif (($row["rght"] - $row["lft"] > 1) && ($row["rght"] > $p_right)){
        $result. "<ul>";
        $result.= "<li>".$row['title']."</li>";

      }else{
        $result.= "<li>".$row['title']."</li>";
      } 

      $p_right = $row["rght"];
      $p_left = $row["lft"];
      $p_diff = $diff;
    }
  }
  $result.= "</ul>";
  return $result;
} 

Here is my sample table:

这是我的示例表:

|ID  |  TITLE | lft| rght |
|1   | Cat 1  | 1      |    16       |
|18  | Cat 2  | 3      |    4       |
|22  | Cat 3  | 5      |    6       |
|28  | Cat 4  | 7      |    8       |
|34  | Cat 5  | 9      |    9       |
|46  | Cat 6  | 11      |    10       |
|47  | Cat 7  | 13      |    12       |
|49  | Cat 8  | 15      |    14       | 

Now it outputs something like:

现在它输出如下:

    <ul>
<li>Cat 1</li>
<li>Cat 2</li>
<li>Cat 3</li>
<li>Cat 4</li>
<li>Cat 5</li>
<li>Cat 6</li>
<li>Cat 7</li>
<li>Cat 8</li>
</ul>

Can anyone tell me why or how it will output the list in hierarchical a structure?

任何人都可以告诉我为什么或如何在分层结构中输出列表?

Related topic

相关主题

7 个解决方案

#1


51  

Ok, let's do some bounty hunting ;)

好吧,让我们做一些赏金的狩猎;)

Step 0 - Sanitize example:
As already mentioned, your example data is broken, as it does not define a valid nested set. If you took this data from an app, you should check the insert/delete logic.

步骤0 - 清理示例:如前所述,您的示例数据已损坏,因为它未定义有效的嵌套集。如果从应用程序中获取此数据,则应检查插入/删除逻辑。

So for testing, I used a sanitized version like so:
(MySQL here, as it was the first at hand)

所以对于测试,我使用了一个像这样的清理版本:( MySQL在这里,因为它是第一个手头)

CREATE TABLE t_categories`(
  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(45) NOT NULL,
  `lft` INTEGER UNSIGNED NOT NULL,
  `rght` INTEGER UNSIGNED NOT NULL,
  PRIMARY KEY (`id`)
);

INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 1',1,16);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 2',2,3);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 3',4,7);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 4',5,6);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 5',8,13);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 6',9,12);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 7',10,11);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 8',14,15);

Step 1 - Let the database do the ordering
Nested sets where primarily invented as a convenient way of storing trees in databases, as they make it pretty easy to query for subtrees, parent relations and, especially interesting in this case, for order and depth:

步骤1 - 让数据库执行排序嵌套集合,主要是作为在数据库中存储树的方便方法发明的,因为它们可以很容易地查询子树,父关系,在这种情况下,对于顺序和深度尤其有趣:

SELECT node.title, (COUNT(parent.title) - 1) AS depth
 FROM t_categories AS node
 CROSS JOIN t_categories AS parent
 WHERE node.lft BETWEEN parent.lft AND parent.rght
 GROUP BY node.title
 ORDER BY node.lft

This will return your set neatly ordered, starting with the root node and continuing to the end in preorder. Most importantly, it will add the depth of each node as a positive integer, indicating how many levels the node is below root (level 0). For the above example data, the result will be:

这将返回整齐排序的集合,从根节点开始并按预订继续到最后。最重要的是,它会将每个节点的深度添加为正整数,表示节点在根目录下的级别(级别0)。对于上面的示例数据,结果将是:

title, depth
'Cat 1', 0
'Cat 2', 1
'Cat 3', 1
'Cat 4', 2
'Cat 5', 1
'Cat 6', 2
'Cat 7', 3
'Cat 8', 1

In code:

在代码中:

// Grab ordered data
$query = '';
$query .= 'SELECT node.title, (COUNT(parent.title) - 1) AS depth';
$query .= ' FROM t_categories AS node';
$query .= ' CROSS JOIN t_categories AS parent';
$query .= ' WHERE node.lft BETWEEN parent.lft AND parent.rght';
$query .= ' GROUP BY node.title';
$query .= ' ORDER BY node.lft';

$result = mysql_query($query);

// Build array
$tree = array();
while ($row = mysql_fetch_assoc($result)) {
  $tree[] = $row;
}

The resulting array will look like this:

结果数组将如下所示:

Array
(
    [0] => Array
        (
            [title] => Cat 1
            [depth] => 0
        )

    [1] => Array
        (
            [title] => Cat 2
            [depth] => 1
        )
    ...
)

Step 2 - Output as HTML list fragment:

第2步 - 输出为HTML列表片段:

Using while loop:

使用while循环:

// bootstrap loop
$result = '';
$currDepth = -1;  // -1 to get the outer <ul>
while (!empty($tree)) {
  $currNode = array_shift($tree);
  // Level down?
  if ($currNode['depth'] > $currDepth) {
    // Yes, open <ul>
    $result .= '<ul>';
  }
  // Level up?
  if ($currNode['depth'] < $currDepth) {
    // Yes, close n open <ul>
    $result .= str_repeat('</ul>', $currDepth - $currNode['depth']);
  }
  // Always add node
  $result .= '<li>' . $currNode['title'] . '</li>';
  // Adjust current depth
  $currDepth = $currNode['depth'];
  // Are we finished?
  if (empty($tree)) {
    // Yes, close n open <ul>
    $result .= str_repeat('</ul>', $currDepth + 1);
  }
}

print $result;

Same logic as recursive function:

与递归函数相同的逻辑:

function renderTree($tree, $currDepth = -1) {
  $currNode = array_shift($tree);
  $result = '';
  // Going down?
  if ($currNode['depth'] > $currDepth) {
    // Yes, prepend <ul>
    $result .= '<ul>';
  }
  // Going up?
  if ($currNode['depth'] < $currDepth) {
    // Yes, close n open <ul>
    $result .= str_repeat('</ul>', $currDepth - $currNode['depth']);
  }
  // Always add the node
  $result .= '<li>' . $currNode['title'] . '</li>';
  // Anything left?
  if (!empty($tree)) {
    // Yes, recurse
    $result .=  renderTree($tree, $currNode['depth']);
  }
  else {
    // No, close remaining <ul>
    $result .= str_repeat('</ul>', $currNode['depth'] + 1);
  }
  return $result;
}

print renderTree($tree);

Both will output the following structure:

两者都将输出以下结构:

<ul>
    <li>Cat 1</li>
    <li>
        <ul>
            <li>Cat 2</li>
            <li>Cat 3</li>
            <li>
                <ul>
                    <li>Cat 4</li>
                </ul>
            </li>
            <li>Cat 5</li>
            <li>
                <ul>
                    <li>Cat 6</li>
                    <li>
                        <ul>
                            <li>Cat 7</li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li>Cat 8</li>
        </ul>
    </li>
</ul>

Nitpickers corner: Questioner explicitly asked for <ul>, but ordered unordered lists!? Come on...
;-)

Nitpickers角落:提问者明确要求

    ,但订购了无序列表!?来吧... ;-)

#2


16  

Better Render Tree Function that worked for me (php function to prepare html source for use in jsTree jQuery plugin) instead of the Henrik Opel's one:

更好的渲染树函数对我有用(php函数准备用于jsTree jQuery插件的html源代码)而不是Henrik Opel的一个:

function MyRenderTree ( $tree = array(array('name'=>'','depth'=>'')) ){

$current_depth = 0;
$counter = 0;

$result = '<ul>';

foreach($tree as $node){
    $node_depth = $node['depth'];
    $node_name = $node['name'];
    $node_id = $node['category_id'];

    if($node_depth == $current_depth){
        if($counter > 0) $result .= '</li>';            
    }
    elseif($node_depth > $current_depth){
        $result .= '<ul>';
        $current_depth = $current_depth + ($node_depth - $current_depth);
    }
    elseif($node_depth < $current_depth){
        $result .= str_repeat('</li></ul>',$current_depth - $node_depth).'</li>';
        $current_depth = $current_depth - ($current_depth - $node_depth);
    }
    $result .= '<li id="c'.$node_id.'"';
    $result .= $node_depth < 2 ?' class="open"':'';
    $result .= '><a href="#"><ins>&nbsp;</ins>'.$node_name.'</a>';
    ++$counter;
}
 $result .= str_repeat('</li></ul>',$node_depth).'</li>';

$result .= '</ul>';

return $result;}

Result HTML:

结果HTML:

<ul>
    <li id="c1" class="open"><a href="#"><ins>&nbsp;</ins>ELECTRONICS</a>
        <ul>
            <li id="c2" class="open"><a href="#"><ins>&nbsp;</ins>TELEVISIONS</a>
                <ul>
                    <li id="c3"><a href="#"><ins>&nbsp;</ins>TUBE</a></li>
                    <li id="c4"><a href="#"><ins>&nbsp;</ins>LCD</a></li>
                    <li id="c5"><a href="#"><ins>&nbsp;</ins>PLASMA</a>
                        <ul>
                            <li id="c14"><a href="#"><ins>&nbsp;</ins>PLASMA1</a></li>
                            <li id="c15"><a href="#"><ins>&nbsp;</ins>PLASMA2</a></li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li id="c6" class="open"><a href="#"><ins>&nbsp;</ins>PORTABLE ELECTRONICS</a>
                <ul>
                    <li id="c7"><a href="#"><ins>&nbsp;</ins>MP3 PLAYERS</a>
                        <ul>
                            <li id="c8"><a href="#"><ins>&nbsp;</ins>FLASH</a></li>
                        </ul>
                    </li>
                    <li id="c9"><a href="#"><ins>&nbsp;</ins>CD PLAYERS</a></li>
                    <li id="c10"><a href="#"><ins>&nbsp;</ins>2 WAY RADIOS</a></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

#3


4  

There's a PEAR package for dealing with nested sets: DB_NestedSet.
You might also be interested in the article Managing Hierarchical Data in MySQL.

有一个用于处理嵌套集的PEAR包:DB_NestedSet。您可能还对管理MySQL中的分层数据这篇文章感兴趣。

#4


1  

This should be what you're looking for:

这应该是你正在寻找的:

function getCats($left = null, $right = null)
{
    $sql = array();
    $result = null;

    if (isset($left) === true)
    {
        $sql[] = 'lft >= ' . intval($left);
    }

    if (isset($right) === true)
    {
        $sql[] = 'rght <= ' . intval($right);
    }

    if (empty($sql) === true)
    {
        $sql[] = 'lft = 1';
    }

    $sql = 'SELECT * FROM t_categories WHERE ' . implode(' AND ', $sql) . ';';

    if ($rs = C_DB::fetchRecordset($sql))
    {
        // you need to make sure that the query returns
        // something to correctly display the ULs
        if (empty($rs) === false)
        {
            $result .= '<ul>' . "\n";

            while ($row = C_DB::fetchRow($rs))
            {
                $result .= '<li>' . $row['title'] . '</li>' . "\n";
                $result .= getCats($row['lft'], $row['rght']);
            }

            $result .= '</ul>' . "\n";
        }
    }

    return $result;
}

To get the HTML for your nested tree you should do:

要获取嵌套树的HTML,您应该:

echo getCats();

Please note that your nested set sample doesn't look right, also you should make sure if I didn't made any mistake invoking your C_DB class, I don't know since I'm not familiarized with it.

请注意,你的嵌套集样本看起来不正确,你应该确保我是否在调用你的C_DB类时没有犯错,我不知道,因为我不熟悉它。

#5


1  

Simply loop thru the result will do:

只需通过结果循环即可:

$sql = "SELECT node.name, (COUNT(parent.name) - 1) AS depth
        FROM nested_category AS node,
        nested_category AS parent
        WHERE node.lft BETWEEN parent.lft AND parent.rgt
        GROUP BY node.name
        ORDER BY node.lft";

$query_result = mysql_query($sql)

$result = "<ul>";
$currDepth = 0;

while($row = mysql_fetch_assoc($query_result))
{
  if($row['depth'] > $currDepth)
  {
    $result .= "<li><ul>"; // open sub tree if level up
  }

  if($row['depth'] < $currDepth)
  {
    $result .= str_repeat("</ul></li>", $currDepth - $row['depth']); // close sub tree if level down
  }

  $result .= "<li>$row['name']</li>"; // Always add node
  $currDepth = $row['depth'];
}
$result .= "</ul>";

echo $result;

#6


0  

$linaje='';
    $lastnode='';
    $sides['izq']=array();
    $sides['der']=array();
    $print = '<ul>'; 
    foreach ($array as $key1 => $value1){ //Proyectos

        if(strpos($info[$key1]['linaje'],'-') !== false)
            $compare = strstr($info[$key1]['linaje'],'-',true);
        else
            $compare  = $info[$key1]['linaje'];

        if($linaje != ''){
            if ($linaje !=   $compare){
                $linaje= $compare;
                $sides['izq']=array();
                $sides['der']=array();
                //for($i=1;$i <= substr_count($lastnode,'`')-substr_count($value1,'`');$i++)
                    //$print .= '</ul></li>';
            }
        }


        if ($lastnode != '')
            for($i=1;$i<= substr_count($lastnode,'`')-substr_count($value1,'`');$i++)
                $print .= '</ul></li>'; 

        if (count($sides['der'])>0)
            if  ($sides['der'][count($sides['der'])-1] > $info[$key1]['der'])
                $print .= '<ul>';

        $print .= '<li><a href="#'.$info[$key1]['id'].'#'.$info[$key1]['linaje'].'">'.substr($value1,substr_count($value1,'`')).'</a>';

        if  ($info[$key1]['der'] - $info[$key1]['izq'] == 1)
                $print .= '</li>';

        if ($key1 == count($info)-1)
            for($i=1;$i <= substr_count($lastnode,'`')-1;$i++)
                $print .= '</ul></li>';

        $sides['der'][] = $info[$key1]['der'];
        $sides['izq'][] = $info[$key1]['izq'];

        if ($linaje =='')
                $linaje = $info[$key1]['linaje'];

        $lastnode = $value1;
    }
    $print .= '</ul>';
    echo $print;

the difference in this is that you can render X numbers of trees, this applies to one of my projects. and I use a char as a depth reference when I fetch the rows from the DB

不同之处在于您可以渲染X个树,这适用于我的一个项目。当我从DB中获取行时,我使用char作为深度引用

#7


0  

i`m using CROSS JOIN query displaying jsTree jQuery menu; Everything works just great ! The existing table I added a column for the position. However, when I define position and ordered all by position, the corresponding items are not grouped properly. I guess it's a query issue, tried many combinations, but no success.

我正在使用CROSS JOIN查询显示jsTree jQuery菜单;一切都很棒!现有表格我为该职位添加了一列。但是,当我定义位置并按位置排序时,相应的项目未正确分组。我想这是一个查询问题,尝试了很多组合,但没有成功。

#1


51  

Ok, let's do some bounty hunting ;)

好吧,让我们做一些赏金的狩猎;)

Step 0 - Sanitize example:
As already mentioned, your example data is broken, as it does not define a valid nested set. If you took this data from an app, you should check the insert/delete logic.

步骤0 - 清理示例:如前所述,您的示例数据已损坏,因为它未定义有效的嵌套集。如果从应用程序中获取此数据,则应检查插入/删除逻辑。

So for testing, I used a sanitized version like so:
(MySQL here, as it was the first at hand)

所以对于测试,我使用了一个像这样的清理版本:( MySQL在这里,因为它是第一个手头)

CREATE TABLE t_categories`(
  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(45) NOT NULL,
  `lft` INTEGER UNSIGNED NOT NULL,
  `rght` INTEGER UNSIGNED NOT NULL,
  PRIMARY KEY (`id`)
);

INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 1',1,16);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 2',2,3);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 3',4,7);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 4',5,6);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 5',8,13);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 6',9,12);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 7',10,11);
INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 8',14,15);

Step 1 - Let the database do the ordering
Nested sets where primarily invented as a convenient way of storing trees in databases, as they make it pretty easy to query for subtrees, parent relations and, especially interesting in this case, for order and depth:

步骤1 - 让数据库执行排序嵌套集合,主要是作为在数据库中存储树的方便方法发明的,因为它们可以很容易地查询子树,父关系,在这种情况下,对于顺序和深度尤其有趣:

SELECT node.title, (COUNT(parent.title) - 1) AS depth
 FROM t_categories AS node
 CROSS JOIN t_categories AS parent
 WHERE node.lft BETWEEN parent.lft AND parent.rght
 GROUP BY node.title
 ORDER BY node.lft

This will return your set neatly ordered, starting with the root node and continuing to the end in preorder. Most importantly, it will add the depth of each node as a positive integer, indicating how many levels the node is below root (level 0). For the above example data, the result will be:

这将返回整齐排序的集合,从根节点开始并按预订继续到最后。最重要的是,它会将每个节点的深度添加为正整数,表示节点在根目录下的级别(级别0)。对于上面的示例数据,结果将是:

title, depth
'Cat 1', 0
'Cat 2', 1
'Cat 3', 1
'Cat 4', 2
'Cat 5', 1
'Cat 6', 2
'Cat 7', 3
'Cat 8', 1

In code:

在代码中:

// Grab ordered data
$query = '';
$query .= 'SELECT node.title, (COUNT(parent.title) - 1) AS depth';
$query .= ' FROM t_categories AS node';
$query .= ' CROSS JOIN t_categories AS parent';
$query .= ' WHERE node.lft BETWEEN parent.lft AND parent.rght';
$query .= ' GROUP BY node.title';
$query .= ' ORDER BY node.lft';

$result = mysql_query($query);

// Build array
$tree = array();
while ($row = mysql_fetch_assoc($result)) {
  $tree[] = $row;
}

The resulting array will look like this:

结果数组将如下所示:

Array
(
    [0] => Array
        (
            [title] => Cat 1
            [depth] => 0
        )

    [1] => Array
        (
            [title] => Cat 2
            [depth] => 1
        )
    ...
)

Step 2 - Output as HTML list fragment:

第2步 - 输出为HTML列表片段:

Using while loop:

使用while循环:

// bootstrap loop
$result = '';
$currDepth = -1;  // -1 to get the outer <ul>
while (!empty($tree)) {
  $currNode = array_shift($tree);
  // Level down?
  if ($currNode['depth'] > $currDepth) {
    // Yes, open <ul>
    $result .= '<ul>';
  }
  // Level up?
  if ($currNode['depth'] < $currDepth) {
    // Yes, close n open <ul>
    $result .= str_repeat('</ul>', $currDepth - $currNode['depth']);
  }
  // Always add node
  $result .= '<li>' . $currNode['title'] . '</li>';
  // Adjust current depth
  $currDepth = $currNode['depth'];
  // Are we finished?
  if (empty($tree)) {
    // Yes, close n open <ul>
    $result .= str_repeat('</ul>', $currDepth + 1);
  }
}

print $result;

Same logic as recursive function:

与递归函数相同的逻辑:

function renderTree($tree, $currDepth = -1) {
  $currNode = array_shift($tree);
  $result = '';
  // Going down?
  if ($currNode['depth'] > $currDepth) {
    // Yes, prepend <ul>
    $result .= '<ul>';
  }
  // Going up?
  if ($currNode['depth'] < $currDepth) {
    // Yes, close n open <ul>
    $result .= str_repeat('</ul>', $currDepth - $currNode['depth']);
  }
  // Always add the node
  $result .= '<li>' . $currNode['title'] . '</li>';
  // Anything left?
  if (!empty($tree)) {
    // Yes, recurse
    $result .=  renderTree($tree, $currNode['depth']);
  }
  else {
    // No, close remaining <ul>
    $result .= str_repeat('</ul>', $currNode['depth'] + 1);
  }
  return $result;
}

print renderTree($tree);

Both will output the following structure:

两者都将输出以下结构:

<ul>
    <li>Cat 1</li>
    <li>
        <ul>
            <li>Cat 2</li>
            <li>Cat 3</li>
            <li>
                <ul>
                    <li>Cat 4</li>
                </ul>
            </li>
            <li>Cat 5</li>
            <li>
                <ul>
                    <li>Cat 6</li>
                    <li>
                        <ul>
                            <li>Cat 7</li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li>Cat 8</li>
        </ul>
    </li>
</ul>

Nitpickers corner: Questioner explicitly asked for <ul>, but ordered unordered lists!? Come on...
;-)

Nitpickers角落:提问者明确要求

    ,但订购了无序列表!?来吧... ;-)

#2


16  

Better Render Tree Function that worked for me (php function to prepare html source for use in jsTree jQuery plugin) instead of the Henrik Opel's one:

更好的渲染树函数对我有用(php函数准备用于jsTree jQuery插件的html源代码)而不是Henrik Opel的一个:

function MyRenderTree ( $tree = array(array('name'=>'','depth'=>'')) ){

$current_depth = 0;
$counter = 0;

$result = '<ul>';

foreach($tree as $node){
    $node_depth = $node['depth'];
    $node_name = $node['name'];
    $node_id = $node['category_id'];

    if($node_depth == $current_depth){
        if($counter > 0) $result .= '</li>';            
    }
    elseif($node_depth > $current_depth){
        $result .= '<ul>';
        $current_depth = $current_depth + ($node_depth - $current_depth);
    }
    elseif($node_depth < $current_depth){
        $result .= str_repeat('</li></ul>',$current_depth - $node_depth).'</li>';
        $current_depth = $current_depth - ($current_depth - $node_depth);
    }
    $result .= '<li id="c'.$node_id.'"';
    $result .= $node_depth < 2 ?' class="open"':'';
    $result .= '><a href="#"><ins>&nbsp;</ins>'.$node_name.'</a>';
    ++$counter;
}
 $result .= str_repeat('</li></ul>',$node_depth).'</li>';

$result .= '</ul>';

return $result;}

Result HTML:

结果HTML:

<ul>
    <li id="c1" class="open"><a href="#"><ins>&nbsp;</ins>ELECTRONICS</a>
        <ul>
            <li id="c2" class="open"><a href="#"><ins>&nbsp;</ins>TELEVISIONS</a>
                <ul>
                    <li id="c3"><a href="#"><ins>&nbsp;</ins>TUBE</a></li>
                    <li id="c4"><a href="#"><ins>&nbsp;</ins>LCD</a></li>
                    <li id="c5"><a href="#"><ins>&nbsp;</ins>PLASMA</a>
                        <ul>
                            <li id="c14"><a href="#"><ins>&nbsp;</ins>PLASMA1</a></li>
                            <li id="c15"><a href="#"><ins>&nbsp;</ins>PLASMA2</a></li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li id="c6" class="open"><a href="#"><ins>&nbsp;</ins>PORTABLE ELECTRONICS</a>
                <ul>
                    <li id="c7"><a href="#"><ins>&nbsp;</ins>MP3 PLAYERS</a>
                        <ul>
                            <li id="c8"><a href="#"><ins>&nbsp;</ins>FLASH</a></li>
                        </ul>
                    </li>
                    <li id="c9"><a href="#"><ins>&nbsp;</ins>CD PLAYERS</a></li>
                    <li id="c10"><a href="#"><ins>&nbsp;</ins>2 WAY RADIOS</a></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

#3


4  

There's a PEAR package for dealing with nested sets: DB_NestedSet.
You might also be interested in the article Managing Hierarchical Data in MySQL.

有一个用于处理嵌套集的PEAR包:DB_NestedSet。您可能还对管理MySQL中的分层数据这篇文章感兴趣。

#4


1  

This should be what you're looking for:

这应该是你正在寻找的:

function getCats($left = null, $right = null)
{
    $sql = array();
    $result = null;

    if (isset($left) === true)
    {
        $sql[] = 'lft >= ' . intval($left);
    }

    if (isset($right) === true)
    {
        $sql[] = 'rght <= ' . intval($right);
    }

    if (empty($sql) === true)
    {
        $sql[] = 'lft = 1';
    }

    $sql = 'SELECT * FROM t_categories WHERE ' . implode(' AND ', $sql) . ';';

    if ($rs = C_DB::fetchRecordset($sql))
    {
        // you need to make sure that the query returns
        // something to correctly display the ULs
        if (empty($rs) === false)
        {
            $result .= '<ul>' . "\n";

            while ($row = C_DB::fetchRow($rs))
            {
                $result .= '<li>' . $row['title'] . '</li>' . "\n";
                $result .= getCats($row['lft'], $row['rght']);
            }

            $result .= '</ul>' . "\n";
        }
    }

    return $result;
}

To get the HTML for your nested tree you should do:

要获取嵌套树的HTML,您应该:

echo getCats();

Please note that your nested set sample doesn't look right, also you should make sure if I didn't made any mistake invoking your C_DB class, I don't know since I'm not familiarized with it.

请注意,你的嵌套集样本看起来不正确,你应该确保我是否在调用你的C_DB类时没有犯错,我不知道,因为我不熟悉它。

#5


1  

Simply loop thru the result will do:

只需通过结果循环即可:

$sql = "SELECT node.name, (COUNT(parent.name) - 1) AS depth
        FROM nested_category AS node,
        nested_category AS parent
        WHERE node.lft BETWEEN parent.lft AND parent.rgt
        GROUP BY node.name
        ORDER BY node.lft";

$query_result = mysql_query($sql)

$result = "<ul>";
$currDepth = 0;

while($row = mysql_fetch_assoc($query_result))
{
  if($row['depth'] > $currDepth)
  {
    $result .= "<li><ul>"; // open sub tree if level up
  }

  if($row['depth'] < $currDepth)
  {
    $result .= str_repeat("</ul></li>", $currDepth - $row['depth']); // close sub tree if level down
  }

  $result .= "<li>$row['name']</li>"; // Always add node
  $currDepth = $row['depth'];
}
$result .= "</ul>";

echo $result;

#6


0  

$linaje='';
    $lastnode='';
    $sides['izq']=array();
    $sides['der']=array();
    $print = '<ul>'; 
    foreach ($array as $key1 => $value1){ //Proyectos

        if(strpos($info[$key1]['linaje'],'-') !== false)
            $compare = strstr($info[$key1]['linaje'],'-',true);
        else
            $compare  = $info[$key1]['linaje'];

        if($linaje != ''){
            if ($linaje !=   $compare){
                $linaje= $compare;
                $sides['izq']=array();
                $sides['der']=array();
                //for($i=1;$i <= substr_count($lastnode,'`')-substr_count($value1,'`');$i++)
                    //$print .= '</ul></li>';
            }
        }


        if ($lastnode != '')
            for($i=1;$i<= substr_count($lastnode,'`')-substr_count($value1,'`');$i++)
                $print .= '</ul></li>'; 

        if (count($sides['der'])>0)
            if  ($sides['der'][count($sides['der'])-1] > $info[$key1]['der'])
                $print .= '<ul>';

        $print .= '<li><a href="#'.$info[$key1]['id'].'#'.$info[$key1]['linaje'].'">'.substr($value1,substr_count($value1,'`')).'</a>';

        if  ($info[$key1]['der'] - $info[$key1]['izq'] == 1)
                $print .= '</li>';

        if ($key1 == count($info)-1)
            for($i=1;$i <= substr_count($lastnode,'`')-1;$i++)
                $print .= '</ul></li>';

        $sides['der'][] = $info[$key1]['der'];
        $sides['izq'][] = $info[$key1]['izq'];

        if ($linaje =='')
                $linaje = $info[$key1]['linaje'];

        $lastnode = $value1;
    }
    $print .= '</ul>';
    echo $print;

the difference in this is that you can render X numbers of trees, this applies to one of my projects. and I use a char as a depth reference when I fetch the rows from the DB

不同之处在于您可以渲染X个树,这适用于我的一个项目。当我从DB中获取行时,我使用char作为深度引用

#7


0  

i`m using CROSS JOIN query displaying jsTree jQuery menu; Everything works just great ! The existing table I added a column for the position. However, when I define position and ordered all by position, the corresponding items are not grouped properly. I guess it's a query issue, tried many combinations, but no success.

我正在使用CROSS JOIN查询显示jsTree jQuery菜单;一切都很棒!现有表格我为该职位添加了一列。但是,当我定义位置并按位置排序时,相应的项目未正确分组。我想这是一个查询问题,尝试了很多组合,但没有成功。