Intereting Posts
Правильное предотвращение захвата сеанса в PHP Пользовательская таксономия и пользовательский тип сообщения с пользовательским разбиением на страницы 404 не найдены Как создать простой модуль Hello World в Magento? Отправка электронной почты с localhost Кэширование с разбивкой по страницам, очистка от обновления – как решить? Регулярное выражение PHP – удаление всех не-буквенно-цифровых символов Многопоточность в Symfony2 SSL-код PHP-кода должен быть преобразован в Java Внезапная ошибка «сервер MySQL ушла» на сайте PHP Отключить выполнение Javascript на определенных страницах (HTML / PHP) Как остановить сервер-отправленные события как сохранить данные, которые пользователь вводил на странице формы после выполнения скрипта? Наличие опции настраиваемых классов, но унифицированное имя класса Отправка данных JSON с Android на PHP и запись в текстовый файл Усечение текста в PHP?

Как я могу сгенерировать древовидную структуру из таблицы в базе данных?

Я пытаюсь создать древовидную структуру из таблицы в базе данных. Таблица сохраняется в памяти, причем каждая запись имеет родительский_ид или 0. Конечной целью является создание сгенерированного окна выбора и массив узлов.

Код, который у меня есть до сих пор:

function init($table, $parent_id = 0) { $sql = "SELECT id, {$this->parent_id_field}, {$this->name_field} FROM $table WHERE {$this->parent_id_field}=$parent_id ORDER BY display_order"; $result = mysql_query($sql); $this->get_tree($result, 0); print_r($this->nodes); print_r($this->select); exit; } function get_tree($query, $depth = 0, $parent_obj = null) { while($row = mysql_fetch_object($query)) { /* Get node */ $this->nodes[$row->parent_category_id][$row->id] = $row; /* Get select item */ $text = ""; if($row->parent_category_id != 0) { $text .= " "; } $text .= "$row->name"; $this->select[$row->id] = $text; echo "$depth $text\n"; $sql = "SELECT id, parent_category_id, name FROM product_categories WHERE parent_category_id=".$row->id." ORDER BY display_order"; $nextQuery = mysql_query($sql); $rows = mysql_num_rows($nextQuery); if($rows > 0) { $this->get_tree($nextQuery, ++$depth, $row); } } } 

Он почти работает, но не совсем. Может кто-нибудь помочь мне закончить его?

Я думаю, что здесь эта линия:

 if($row->parent_category_id != 0) { $text .= " "; } 

должно быть:

 while ($depth-- > 0) { $text .= " "; } 

Вы отступаете только один раз, а не столько раз, сколько должно быть отступом.

И эта строка:

 $this->get_tree($nextQuery, ++$depth, $row); 

должно быть:

 $this->get_tree($nextQuery, $depth + 1, $row); 

Обратите внимание, что вам, вероятно, следует следовать рекомендациям в другом ответе, и сразу же возьмите всю таблицу, а затем обработайте ее сразу, потому что в целом вы хотите минимизировать круглые поездки в базу данных (есть несколько случаев, когда то, как вы это делаете, более оптимально, например, если у вас очень большое дерево и выбирая небольшую часть, но я сомневаюсь, что это так)

Вы почти наверняка не должны продолжать свой текущий путь. Рекурсивный метод, который вы пытаетесь использовать, почти наверняка убьет вашу производительность, если ваше дерево когда-нибудь станет немного больше. Вероятно, вы должны смотреть на вложенную структуру набора вместо списка смежности, если вы планируете часто читать дерево.

С помощью вложенного набора вы можете легко получить все дерево, вложенное должным образом с помощью одного запроса.

Пожалуйста, ознакомьтесь с этими вопросами для обсуждения деревьев.

Можно ли запросить таблицу древовидной структуры в MySQL в одном запросе на любую глубину?

Реализация иерархической структуры данных в базе данных

Каков наиболее эффективный / элегантный способ разбора плоского стола в дерево?

  $this->nodes[$row->parent_category_id][$row->id] = $row; 

Эта строка уничтожает ваш ORDER BY display_order. Измените его на

  $this->nodes[$row->parent_category_id][] = $row; 

Моя следующая проблема – это часть $ row-> parent_category_id. Разве это не должно быть $ row-> parent_id?

EDIT: О, я не читал ваш источник достаточно близко. Избавиться от предложения WHERE. Прочитайте всю таблицу сразу. Вам нужно отправить процесс обработки дерева во второй раз. Сначала вы читаете базу данных в список массивов. Затем вы обрабатываете массив рекурсивно, чтобы выполнить свой вывод.

Ваш массив должен выглядеть так:

  Array(0 => Array(1 => $obj, 5 => $obj), 1 => Array(2 => $obj), 2 => Array(3 => $obj, 4 => $obj), 5 => Array(6 => $obj) ); function display_tree() { // all the stuff above output_tree($this->nodes[0], 0); // pass all the parent_id = 0 arrays. } function output_tree($nodes, $depth = 0) { foreach($nodes as $k => $v) { echo str_repeat(' ', $depth*2) . $v->print_me(); // print my sub trees output_tree($this->nodes[$k], $depth + 1); } } output: object 1 object 2 object 3 object 4 object 5 object 6