Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Как построить дерево до корня каталога зная id текущего раздела
 
 автор: maxfade   (27.01.2010 в 13:13)   письмо автору
 
 

Добрый день, есть задачка.

Есть каталог, структура примерно такая:


id | parent | name
1     NULL   Корень
2     1      Раздел 1
3     1      Раздел 2
4     1      Раздел 3
5     2      Раздел 1.1


Имея id = 5, необходимо построить дерево до корня каталога, т.е. применительно к таблице выше, получить:
5, 2, 1

Т.е. на выходе массив или список id до корня.

Заранее спасибо...

  Ответить  
 
 автор: Loki   (27.01.2010 в 14:08)   письмо автору
 
   для: maxfade   (27.01.2010 в 13:13)
 

Либо циклом с запросами, либо, если глубина вложенности конечна - одним запросом с алиасами... либо, если элементов не очень много, то одним запросом и последующим циклом в php

  Ответить  
 
 автор: buldovsky   (27.01.2010 в 14:50)   письмо автору
 
   для: 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);
}

?>

  Ответить  
 
 автор: freeing   (27.01.2010 в 14:58)   письмо автору
 
   для: buldovsky   (27.01.2010 в 14:50)
 

можно в примере с $_GET["id"] и scandir(), что-то не понятно!!!!!!!!

  Ответить  
 
 автор: maxfade   (27.01.2010 в 15:12)   письмо автору
 
   для: 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]!=NULLsearch_navigation($n[1],$nav);
    
}
?>


Выдает раздел на один выше... Как быть.

  Ответить  
 
 автор: buldovsky   (27.01.2010 в 15:23)   письмо автору
 
   для: freeing   (27.01.2010 в 14:58)
 

Этот код работает с "двумерным массивом"-таблицей (структуру которой описал автор), где каждая строка имеет уникальный id, а также id родительской строки (parent) и другие поля.

Если вы приведете структуру файлов в ваших директориях к такому виду (с помощью scandir или еще чего-либо), то по id сможете получить список вложенных папок начиная с корня.

  Ответить  
 
 автор: maxfade   (27.01.2010 в 15:58)   письмо автору
 
   для: buldovsky   (27.01.2010 в 15:23)
 

Если не сложно можно пример на базе function для моей задачки...

  Ответить  
 
 автор: maxfade   (28.01.2010 в 10:32)   письмо автору
 
   для: maxfade   (27.01.2010 в 15:58)
 

Ну так что, нет идей?

  Ответить  
 
 автор: Trianon   (28.01.2010 в 10:53)   письмо автору
 
   для: maxfade   (27.01.2010 в 15:58)
 

Это уже называется не пример, а реализация.

  Ответить  
 
 автор: maxfade   (28.01.2010 в 11:40)   письмо автору
 
   для: Trianon   (28.01.2010 в 10:53)
 

Хотя бы, что не корректно или не верно в моем примере 4-мя постами выше.

Реализовывать я не прошу, только совета...

  Ответить  
 
 автор: Trianon   (28.01.2010 в 11:43)   письмо автору
 
   для: maxfade   (28.01.2010 в 11:40)
 

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

  Ответить  
 
 автор: bab-nike   (28.01.2010 в 14:20)   письмо автору
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;
}
?>

  Ответить  
 
 автор: buldovsky   (28.01.2010 в 15:25)   письмо автору
 
   для: bab-nike   (28.01.2010 в 14:20)
 

У вас никогда не возникало мысли о том, что выполнять однотипные операции (а тем более запросы к базе) в цикле это неразумно?

  Ответить  
 
 автор: bab-nike   (28.01.2010 в 16:00)   письмо автору
 
   для: buldovsky   (28.01.2010 в 15:25)
 

возникал и вы правильно заметили, но в данной ситуации в цикл от силы 3..4 раза повторяется, вряд ли кто то захочет на 20...30 или более ступени создать подкаталоги.
P.S. если есть другой вариант, более удобный, то рад буду услышать:)

  Ответить  
 
 автор: maxfade   (28.01.2010 в 16:33)   письмо автору
 
   для: 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
}
?>

  Ответить  
 
 автор: buldovsky   (28.01.2010 в 16:42)   письмо автору
 
   для: 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 строк...

  Ответить  
 
 автор: Рома   (28.01.2010 в 16:33)   письмо автору
 
   для: buldovsky   (28.01.2010 в 15:25)
 

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

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования