2012-02-07 2 views
1

Я читал эту статью, http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/.SQL Query и 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 | 
+-------------+--------------------+------+------+ 

Я хочу, чтобы иметь возможность отобразить следующий результат в HTML после запроса, а затем манипулировать данными в PHP:

"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

Смежные вопросы