Я читал эту статью, http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ .
Я хотел привести простой пример, а затем спросить, как мне получить желаемый результат? Итак, вот пример:
+---------+-----------------------------+ | 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 для достижения этого результата?
Некоторые особенности, о которых нужно подумать:
Я предполагаю, что печать глубины будет очень важна для построения правильного дерева в HTML.
Я думал, что это хороший вызов. Вот мое решение:
В основном: прочитайте узел, тогда все следующие узлы с 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());