2012-01-07 4 views
0

Как я могу построить этот HTML код:Построение дерева с использованием вложенных неупорядоченных списков

<ul class="tree"> 
    <li>Animals 
     <ul> 
      <li>Birds</li> 
      <li>Mammals 
       <ul> 
        <li>Elephant</li> 
        <li>Mouse</li> 
       </ul> 
      </li> 
      <li>Reptiles</li> 
     </ul> 
    </li> 
    <li>Plants 
     <ul> 
      <li>Flowers 
       <ul> 
        <li>Rose</li> 
        <li>Tulip</li> 
       </ul> 
      </li> 
      <li>Trees</li> 
     </ul> 
    </li> 
</ul> 

Из этой структуры:

CREATE TABLE `categories` (
    `id` INT(11) NOT NULL AUTO_INCREMENT, 
    `position` INT(11) DEFAULT NULL, 
    `parent_id` INT(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `parent_id_fk` (`parent_id`), 
    CONSTRAINT `categories_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `categories` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

INSERT INTO `categories` (`id`, `position`, `parent_id`) 
VALUES 
    (1,1,NULL), 
    (2,2,NULL), 
    (3,1,1), 
    (4,2,1), 
    (5,1,4), 
    (6,2,4), 
    (7,3,1), 
    (8,1,2), 
    (9,1,8), 
    (10,2,8), 
    (11,2,2); 

CREATE TABLE `categories_locale` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `slug` VARCHAR(100) NOT NULL DEFAULT '', 
    `name` VARCHAR(40) NOT NULL DEFAULT '', 
    `path_cache` text, 
    `category_id` INT(11) NOT NULL, 
    `locale_id` SMALLINT(5) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

INSERT INTO `categories_locale` (`id`, `slug`, `name`, `path_cache`, `category_id`, `locale_id`) 
VALUES 
    (1,'animals','Animals',NULL,1,1), 
    (2,'plants','Plants',NULL,2,1), 
    (3,'birds','Birds',NULL,3,1), 
    (4,'mammals','Mammals',NULL,4,1), 
    (5,'elephant','Elephant',NULL,5,1), 
    (6,'mouse','Mouse',NULL,6,1), 
    (7,'reptiles','Reptiles',NULL,7,1), 
    (8,'flowers','Flowers',NULL,8,1), 
    (9,'rose','Rose',NULL,9,1), 
    (10,'tulip','Tulip',NULL,10,1), 
    (11,'trees','Trees',NULL,11,1); 
+0

Не так много. Я застрял после создания SQL и HTML. Я понятия не имею, как это сделать. – oaziz

+1

Это может помочь вам приступить к работе http://stackoverflow.com/questions/5291054/hierarchical-sql-problem/5291159#5291159 –

ответ

1

Хм, я считаю, должны быть примеры, доступные в Интернете, как вы можете это сделать. Некоторые из них могут даже говорить о новых способах хранения иерархических данных, и вы найдете интересные показания.

В любом случае этот фрагмент кода, основанный на рекурсии, может помочь вам достичь вашего HTML.

<?php 
// recursive function to generate the category HTML 
function generateTree ($parent) { 
    global $arrPCat, $arrCat; 
    if (array_key_exists($parent, $arrPCat)) { 
     echo '<ul' . ($parent == 0 ? ' class="tree"' : '') . '>'; 
     foreach ($arrPCat[$parent] as $arrC) { 
      echo '<li>' . $arrC['name'] . '</li>'; 
      generateTree($arrC['id']); 
     } 
     echo '</ul>'; 
    } 
} 

// read all categories from the DB 
$rs = mysql_query('SELECT `cl`.`id`, `cl`.`name`, `c`.`position`, IFNULL(`c`.`parent_id`, 0) AS `parent_id` 
    FROM `categories_locale` `cl` 
    LEFT JOIN `categories` `c` ON `cl`.`id` = `c`.`id` 
    ORDER BY `c`.`parent_id` , `c`.`position`'); 
while ($r = mysql_fetch_assoc($rs)) { 
    // store parent and its children into the $arrPCat Array 
    $arrPCat[$r['parent_id']][] = Array (
            'id' => $r['id'], 
            'name' => $r['name'] 
           ); 
} 
generateTree (0); // now generate the HTML for the category tree 
?> 

Надеюсь, это поможет!

+0

Очень полезно, спасибо. – oaziz

+0

Это довольно плохой способ построения дерева, поскольку для него требуется несколько SQL-запросов. Лучшим вариантом было бы получить все категории в 1 запросе и построить дерево с помощью функций массива PHP. Вышеприведенный код может быть улучшен путем кэширования окончательного HTML и чтения этого из временного файла. –

+0

@AlexHolsgrove, приведенный выше код выполняет один запрос, а не несколько запросов. Не уверен, правильно ли я вас понял – Abhay

0

Попробуйте строить реальное дерево в PHP, а затем с помощью поиска в глубину для генерации HTML.

0

Есть небольшая ошибка, с которой я сталкиваюсь с ответом Абхая. Его решение не делает UL вложенным в LI, по крайней мере, когда я реализую его решение. Тем не менее, это быстрое решение. Вам просто нужно повторить закрывающий тег li после рекурсивного вызова. Это позволяет полностью создать элемент списка, даже если он не имеет каких-либо подпунктов, до его окончания.

код Абхая:

foreach ($arrPCat[$parent] as $arrC) { 
     echo '<li>' . $arrC['name'] . '</li>'; 
     generateTree($arrC['id']); 
    } 

Коррекция:

foreach ($arrPCat[$parent] as $arrC) { 
     echo '<li>' . $arrC['name'] ; 
     generateTree($arrC['id']); 
     echo '</li>'; 
    } 
Смежные вопросы