|
|
|
| Добрый день, есть задачка.
Есть каталог, структура примерно такая:
id | parent | name
1 NULL Корень
2 1 Раздел 1
3 1 Раздел 2
4 1 Раздел 3
5 2 Раздел 1.1
|
Имея id = 5, необходимо построить дерево до корня каталога, т.е. применительно к таблице выше, получить:
5, 2, 1
Т.е. на выходе массив или список id до корня.
Заранее спасибо... | |
|
|
|
|
|
|
|
для: maxfade
(27.01.2010 в 13:13)
| | Либо циклом с запросами, либо, если глубина вложенности конечна - одним запросом с алиасами... либо, если элементов не очень много, то одним запросом и последующим циклом в php | |
|
|
|
|
|
|
|
для: maxfade
(27.01.2010 в 13:13)
| | Этот код сделает почти то что вам нужно
<?php
// пусть $folders это ваш каталог
// пусть $parent - родитель с которого нужно начинать путь наверх к корню
// $folder_levels - результат
$folder_levels = array();
// не имеет смысла заваривать кашу если мы и так в корне
if($parent != 0){
// начальное значение для цикла
$level = $parent;
while($level > 0){
// заносим строку из каталога в результат
$folder_levels[] = $folders[$level];
// поднимаемся на уровень выше для продолжения цикла
$level = $folders[$level]["parent"];
}
// переворачиваем результат с головы на ноги
$folder_levels = array_reverse($folder_levels);
}
?>
|
| |
|
|
|
|
|
|
|
для: buldovsky
(27.01.2010 в 14:50)
| | можно в примере с $_GET["id"] и scandir(), что-то не понятно!!!!!!!! | |
|
|
|
|
|
|
|
для: freeing
(27.01.2010 в 14:58)
| | Забыл сказать самое главное, каталог в БД MySQL
Пробовал так:
<?
function search_navigation($id,$nav)
{
$navigation_view = mysql_query("SELECT id, parent FROM textbook WHERE id = '".$id."'");
if ($navigation_view) $n = mysql_fetch_row($navigation_view); else echo "<div style='background:#f8e6e6;border:1px solid #cdcdcd;padding:5px;'>".mysql_error()."</div>";
$array_list[] = $n[0];
array_push($array_list,$nav);
if (count($array_list)>1) $arr_add = implode(",",$array_list);
if ($n[0]!=NULL) search_navigation($n[1],$nav);
}
?>
|
Выдает раздел на один выше... Как быть. | |
|
|
|
|
|
|
|
для: freeing
(27.01.2010 в 14:58)
| | Этот код работает с "двумерным массивом"-таблицей (структуру которой описал автор), где каждая строка имеет уникальный id, а также id родительской строки (parent) и другие поля.
Если вы приведете структуру файлов в ваших директориях к такому виду (с помощью scandir или еще чего-либо), то по id сможете получить список вложенных папок начиная с корня. | |
|
|
|
|
|
|
|
для: buldovsky
(27.01.2010 в 15:23)
| | Если не сложно можно пример на базе function для моей задачки... | |
|
|
|
|
|
|
|
для: maxfade
(27.01.2010 в 15:58)
| | Ну так что, нет идей? | |
|
|
|
|
|
|
|
для: maxfade
(27.01.2010 в 15:58)
| | Это уже называется не пример, а реализация. | |
|
|
|
|
|
|
|
для: Trianon
(28.01.2010 в 10:53)
| | Хотя бы, что не корректно или не верно в моем примере 4-мя постами выше.
Реализовывать я не прошу, только совета... | |
|
|
|
|
|
|
|
для: maxfade
(28.01.2010 в 11:40)
| | некорректно уже то, что Вы используете рекурсию.
Рекурсия для прохода по маршруту от узла дерева до корня не нужна.
Это не ветвящийся процесс. | |
|
|
|
|
132.4 Кб |
|
|
для: maxfade
(27.01.2010 в 13:13)
| | как я понял хотите форум написать да? у меня есть пример, отлично работающий, сейчас поищу, пару месяцев назад написал, затерялся где то...
Только у меня Корень принимает значение 0, цикл повторяется до тех пор, пока $parent не становится 0, и выводит результат в виде ссылки, как на картинке
<?php
function title($parent, $database_forum, $forum)
{
if ($parent=='0') $tmp_par='Форум - Главная';
else {
while ($parent!=0)
{
mysql_select_db($database_forum, $forum);
$query_parr = sprintf("SELECT * FROM forum_cat WHERE id = %s", $parent);
$parr = mysql_query($query_parr, $forum) or die(mysql_error());
$row_parr = mysql_fetch_assoc($parr);
$parent=$row_parr['id_cat'];
$parent_id=$row_parr['id'];
$tmp=$row_parr['name'];
$tmp_par="<a href=index.php?parent=".$parent_id.">[".$tmp."]</a> ".$tmp_par;
}
}
return $tmp_par;
}
?>
|
| |
|
|
|
|
|
|
|
для: bab-nike
(28.01.2010 в 14:20)
| | У вас никогда не возникало мысли о том, что выполнять однотипные операции (а тем более запросы к базе) в цикле это неразумно? | |
|
|
|
|
|
|
|
для: buldovsky
(28.01.2010 в 15:25)
| | возникал и вы правильно заметили, но в данной ситуации в цикл от силы 3..4 раза повторяется, вряд ли кто то захочет на 20...30 или более ступени создать подкаталоги.
P.S. если есть другой вариант, более удобный, то рад буду услышать:) | |
|
|
|
|
|
|
|
для: bab-nike
(28.01.2010 в 16:00)
| | Всем спасибо, нашел решение, которое меня полностью устраивает, возможно и другим будет интересно.
Как всегда все гениальное, просто: :)
<?
function search_navigation($parent) {
// Проверяем парен на уровень выше и берем id
$result = mysql_query("SELECT id, parent FROM textbook WHERE id = '".$parent."'");
$row = mysql_fetch_array($result);
// добавляем массив
$path = array();
// если парент не NULL
if ($row['parent']!=NULL)
{
// добавляем id в массив
$path[] = $row['id'];
// склеиваем массивы
$path = array_merge(search_navigation($row['parent']), $path);
}
// возвращаем массив со списком id
return $path;
}
?>
|
| |
|
|
|
|
|
|
|
для: bab-nike
(28.01.2010 в 16:00)
| | Во-первых, выбирать одну и ту же базу данных в цикле это равносильно тому, что говорить "Здравствуйте, меня зовут bab-nike!" каждый раз в начале очередной фразы при разговоре с человеком. Как вы думаете ваш собеседник не поймет этого, если вы скажете это 1 раз перед разговором (а не 100 за разговор)?
А по поводу запросов, я зашел в phpmyadmin и посмотрел:
Запрос возвращает 1 запись за 0.0019 - 0.0020 сек
SELECT SQL_NO_CACHE * FROM `table` WHERE `id`='5'
|
Состояние Время
starting 0.000078
checking query cache for query 0.000068
checking permissions 0.000025
Opening tables 0.000031
System lock 0.000019
Table lock 0.000024
init 0.000053
optimizing 0.000023
statistics 0.000186
preparing 0.000086
executing 0.000018
Sending data 0.000128
end 0.000024
end 0.000017
query end 0.000023
freeing items 0.000025
closing tables 0.000025
logging slow query 0.000018
cleaning up 0.000025
|
Запрос возвращает 50 записей (именно о таких цифрах мы говорим) за те же 0.0020 - 0.0022 сек.
SELECT SQL_NO_CACHE * FROM `table` LIMIT 50
|
Состояние Время
starting 0.000051
checking query cache for query 0.000052
checking permissions 0.000013
Opening tables 0.000021
System lock 0.000013
Table lock 0.000018
init 0.000036
optimizing 0.000014
statistics 0.000028
preparing 0.000023
executing 0.000012
Sending data 0.000298
end 0.000012
end 0.000009
query end 0.000010
freeing items 0.000011
closing tables 0.000013
logging slow query 0.000012
cleaning up 0.000009
|
Исходя из здравого смысла если
Вытащить 50 строк приблизительно столько же по времени как и вытащить 1 строку
следовательно
Вытащить 1 строку 5 раз в разы дольше чем вытащить 50 строк за раз,
Другое дело 500 строк... | |
|
|
|
|
|
|
|
для: buldovsky
(28.01.2010 в 15:25)
| | иногда, чтобы увеличить скорость генерации страницы, разумней выполнить запрос в цикле, а не тащить все данные одним тяжелым запросом. | |
|
|
|