2012-02-07 51 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