2012-02-07 52 views
1

我正在阅读这篇文章,http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/使用嵌套集模型进行SQL查询和PHP操作

我想给一个简单的例子,然后问你如何得到想要的结果?因此,这里的例子:

+---------+-----------------------------+ 
| product_id | product_name   | 
+---------+-----------------------------+ 
|   1 | Example Product   | 
+---------+-----------------------------+ 
+---------+-----------------------------+ 
| product_id | category_id    | 
+---------+-----------------------------+ 
|   1 | 2      | 
|   1 | 4      | 
+---------+-----------------------------+ 
+-------------+--------------------+------+------+ 
| category_id | name     | lft | rgt | 
+-------------+--------------------+------+------+ 
|   1 | Electronics   | 1 | 8 | 
|   2 | Televisions   | 2 | 3 | 
|   3 | Portable Electronics | 4 | 7 | 
|   4 | CD Players   | 5 | 6 | 
+-------------+--------------------+------+------+ 

我希望能够在PHP查询,然后操纵数据后显示在HTML以下结果:

"Example Product" Categories: 
Electronics 
    Televisions 
    Portable Electronics 
     CD Players 

你能帮走我通过查询并在PHP中操作来实现这个结果?

一些具体思考:

  1. 注意两类如何电子之下,但“电子”仅出现一次在这里,显示每个属于以下
  2. 结果最终应子类别一个PHP多维数组,其类别包含一个子类别数组,每个子类别包含一个子子类别数组(如果存在的话)。

我想打印深度对于在HTML中构建正确的树非常重要。

回答

3

我认为这是一个很好的挑战。这里是我的解决方案:

基本上是:读一个节点,比你rgt是你的孩子小,然后用rgt所有以下节点,这样做递归。 我用peek/consume像你平常那样从mysql读取数据。

如果查询没有结果,或者数据集是中断,脚本将会中断或循环。

class NestedNodeReader { 

    private $mysql_result; 
    private $peeked = false; 
    private $last_peek; 

    public function __construct($mysql_result) { 
     $this->mysql_result = $mysql_result; 
    } 

    public function getTree() { 
     $root = $this->consume(); 
     $root["children"] = $this->getSubTree($root["rgt"]); 
     return $root; 
    } 

    private function getSubTree($stop_at) { 
     $nodes = array(); 
     $node = $this->peek(); 
     while ($node["rgt"] < $stop_at) { 
      $node = $this->consume(); 
      $node["children"] = $this->getSubTree($node["rgt"]); 
      $nodes[] = $node; 
      $node = $this->peek(); 
      if (false === $node) { 
       break; 
      } 
     } 
     return $nodes; 
    } 

    private function peek() { 
     if (false === $this->peeked) { 
      $this->peeked = true; 
      $this->last_peek = mysql_fetch_assoc($this->mysql_result); 
     } 
     return $this->last_peek; 
    } 

    private function consume() { 
     if (false === $this->peeked) { 
      return mysql_fetch_assoc($this->mysql_result); 
     } else { 
      $this->peeked = false; 
      return $this->last_peek; 
     } 
    } 
} 

$query = "SELECT node.name, node.lft, node.rgt 
    FROM nested_category AS node, 
     nested_category AS parent 
    WHERE node.lft BETWEEN parent.lft AND parent.rgt 
     AND parent.name = 'ELECTRONICS' 
    ORDER BY node.lft;" 
$mysql_result = mysql_query($query); 
$nnr = new NestedNodeReader($mysql_result); 
print_r($nnr->getTree()); 
+0

努力工作!对不起,OP当时没有回复你......':-('。 – halfer 2014-11-04 11:40:35