Столкнулся с проблемой построения дерева каталогов на MySQL и PHP. Долго искать не пришлось, поиск сразу подсказал пару хороших статей. Но при их разборе выяснилось что они «слегка» устарели и код из них вообще не захотел работать. Более того они были сильно запутаны. Немного подумав я решил написать свое дерево. О нем то я и напишу сегодня.
С чего начнем?
Ну начнем мы с Базы данных, в таблице у нас будет 3 поля:
- id_tree — id каталога
- id_family — id родительского каталога
- name_tree — имя каталога
Дамп:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
CREATE TABLE IF NOT EXISTS `tree` (
`id_tree` INT(5) NOT NULL AUTO_INCREMENT, `id_family` INT(5) NOT NULL DEFAULT '0', `name_tree` VARCHAR(255) NOT NULL, PRIMARY KEY (`id_tree`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ; INSERT INTO `tree` (`id_tree`, `id_family`, `name_tree`) VALUES (1, 0, 'Folder 1'), (2, 0, 'Folder 2'), (3, 0, 'Folder 3'), (4, 2, 'Folder level 2'), (5, 2, 'Folder level 2'), (6, 4, 'Folder level 3'), (7, 4, 'Folder level 3'), (8, 0, 'Folder 4'), (9, 0, 'Folder 5'); |
Итак, а теперь наши php файлы, начнем с конфига conf.php
1
2 3 4 5 6 7 8 9 10 |
<?php
define ('DB_HOST', 'localhost'); define ('DB_LOGIN', '***'); define ('DB_PASSWORD', '***'); define ('DB_NAME', '***'); $mysql_connect = mysql_connect(DB_HOST, DB_LOGIN, DB_PASSWORD) or die("MySQL Error: " . mysql_error()); mysql_connect(DB_HOST, DB_LOGIN, DB_PASSWORD) or die ("MySQL Error: " . mysql_error()); mysql_query("set names utf8") or die ("<br>Invalid query: " . mysql_error()); mysql_select_db(DB_NAME) or die ("<br>Invalid query: " . mysql_error()); ?> |
Теперь файл с выводом дерева tree.php
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php
include_once('conf.php'); include_once('function.php'); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <link rel="stylesheet" href="/style.css" /> <title>testing directory tree</title> </head> <body> <div class="page"> <div class="tree"> <?php view_tree(); ?> </div> </div> </body> </html> |
Все очень удобно и вывод дерева каталогов мы делаем выводом 1 функции, но для начала подключаем файл с конфигом и функциями.
Ну и самое интересное у нас в файле function.php
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php
function view_tree() { $query = mysql_query("SELECT * FROM `tree`") or die("Извините, произошла ошибка"); while ($row = mysql_fetch_row($query)) { if ($row[1] == '0') { $one_lvl[] = array ($row[0], $row[1], $row[2]); } else { $next_lvl[] = array ($row[0], $row[1], $row[2]); } } print '<ul class="tree_lvl_1">'; foreach ($one_lvl as $key){ print '<li><a href="/?'.$key[0].'">'.$key[2].'</a>'; view_tree_next_level($key[0], $next_lvl); print '</li>'; } print '</ul>'; } function view_tree_next_level($family, $next_lvl) { foreach ($next_lvl as $key) { if ($key[1]==$family) { print '<ul class="tree_lvl_2"><li><a href="/?'.$key[0].'">'.$key[2].'</a>'; view_tree_next_level($key[0], $next_lvl); print '</li></ul>'; } } } ?> |
Итак разберем работу этих функций.
view_tree
Первое что мы делаем это обращаемся к базе данных за данными. А вот далее на 5 строке мы делаем отбор на 2 массива, в $one_lvl мы отбираем все корневые каталоги ( с них мы начнем вывод дерева ) а в $next_lvl мы кладем все остальные каталоги.
В 11 строке мы просто делаем вывод ul для создания списка, далее в 12 мы приходимся по массиву, выводим корневой каталог и вызываем функцию куда передаем id корневого каталога и массив $next_lvl.
А теперь разберем вторую функцию которая отвечает за вложенные каталоги.
view_tree_next_level
На самом деле все просто, мы проходим по массиву в поисках записей у которых id_family совпадает с id_tree. Далее мы выводим эту запись и вызываем эту же функцию для вывода вложенных каталогов в уже вложенный…
Ну и на этом вроде все… Ах да, немного украсим
style.css
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
body, html {
margin:0px; padding:0px; width:100%; height:100%; background-color:#c9c9c9; font-family:Verdana; font-size:12pt; } .tree { margin:10px 10px 10px 10px; width:40%; display:inline-block; float:left; } .tree_lvl_1 { padding-left:20px; list-style-image:url("desing/1299993783_folder.gif"); } .tree_lvl_1 a { COLOR: #000; TEXT-DECORATION: none; } .tree_lvl_1 a:link { COLOR: #000; TEXT-DECORATION: none; } .tree_lvl_1 a:hover { COLOR: #0a0aa1; TEXT-DECORATION: none; } .tree_lvl_1 a:unknown { COLOR: #000; TEXT-DECORATION: none; } .tree_lvl_2 { padding-left:24px; margin-left:-12px; margin-top:-3px; list-style-image:url("desing/folder_2.gif"); border-left:1px solid #000; } |
Теперь действительно все, пользуйтесь