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

Форум PHP

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

 

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

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

тема: рекурсия и скрыте группы по пути?
 
 автор: tAleks   (10.12.2006 в 19:21)   письмо автору
 
 

Есть каталог с бесконечной вложенностью.

Я рекурсивной функцией делаю строку меню:
Группа 1 –> Группа 2 –> Группа 3 –> Группа 4 –> Группа 5

Но предположим, что группа 3 скрыта. И все статьи, которые лежат в группе 3 и ниже, не должны показываться.

А если юзер вызывает статью, которая лежит в 5 группе, по ссылке:
Article.php?id_article=34. Как сделать так чтобы его отправить в группу 2? Т.е. в последнюю не скрытую группу?

   
 
 автор: Trianon   (10.12.2006 в 19:31)   письмо автору
 
   для: tAleks   (10.12.2006 в 19:21)
 

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

   
 
 автор: tAleks   (10.12.2006 в 20:10)   письмо автору
 
   для: Trianon   (10.12.2006 в 19:31)
 

Это тогда получается, что сначала делаем 5 запросов - вычисляем последнюю отметку.
И потом еще 3.
Так?

А можно как-нить за один проход, чтобы запросов было поменьше?

   
 
 автор: Trianon   (10.12.2006 в 20:23)   письмо автору
 
   для: tAleks   (10.12.2006 в 20:10)
 

Объем дерева какой?
И какая предельная глубина?

   
 
 автор: tAleks   (10.12.2006 в 21:46)   письмо автору
 
   для: Trianon   (10.12.2006 в 20:23)
 

Да фиг знает, какая БУДЕТ глубина..... пока глубина 3 пункта...

Вот я че придумал:

<?php 
function menu($code_group)
{
    while(
$code_group 0)
    {
        
// Запрос имени группы и родителя
        
$sql "SELECT name, code_parent, showhide FROM cms_groups WHERE code_group = $code_group LIMIT 1";
        
$query mysql_query($sql);
        
// если запрос не сделан, или сток извлечено < 1 возвращаем FALSE
        
if(!$query || mysql_num_rows($query) < 1) return FALSE;
        
// получаем данные запроса
        
$g[] = mysql_fetch_assoc($query);
        
$code_group $g['code_parent'];
    }
    
    
// Сортируем массив в обратном порядке
    
krsort($g);
    
// Разделитель пунктов меню
    
$separator ' <img src="/Templates/images/arrow.gif" width="9" height="7"> ';
    
// Строим меню, до первой скрытой группы
    
foreach ($g as $k => $v)
    {
        if(
$v['shovhide'] == 'show')
            @
$str .= '<a href="'.$_SERVER['PHP_SELF'].'?code_group='.$code_group.'">'.$g['name'].'</a>'.$separator;
        else
        {
            
// Прервать цикл.
        
}
    }
    return 
$str;
}
?>


Как прервать цикл foreach?

   
 
 автор: Trianon   (10.12.2006 в 21:49)   письмо автору
 
   для: tAleks   (10.12.2006 в 21:46)
 

любой цикл прерывается оператором break;

   
 
 автор: Trianon   (10.12.2006 в 21:50)   письмо автору
 
   для: tAleks   (10.12.2006 в 21:46)
 

я бы считал всё дерево одним запросом, остальную обработку выполняя на PHP-уровне.
как минимум для объема до сотни узлов.
При объеме до десятков тысяч узлов - двумя запросами.
Первый - скелет дерева (id, pid) , второй - данные требуемых узлов.

   
 
 автор: tAleks   (11.12.2006 в 11:55)   письмо автору
 
   для: Trianon   (10.12.2006 в 21:50)
 

>я бы считал всё дерево одним запросом, остальную обработку выполняя на PHP-уровне.
>как минимум для объема до сотни узлов.

Т.е. вообще все группы которые есть. И парралельные ветки тоже. Так?

>При объеме до десятков тысяч узлов - двумя запросами.
>Первый - скелет дерева (id, pid) , второй - данные требуемых узлов.

pid - это, как я понимаю, поле в котором храниться код корневой группы. Правильно? Но у меня в таблице его нет. Оно обязательно, или его целесообразно заводить только при объеме от сотни групп?

   
 
 автор: Trianon   (12.12.2006 в 17:32)   письмо автору
 
   для: tAleks   (11.12.2006 в 11:55)
 

>pid - это, как я понимаю, поле в котором храниться код корневой группы.
pid - parent_id - чужой ключ ключ родительского узла.

>Правильно? Но у меня в таблице его нет.
если ключа родителя нет, то как у вас узлы связаны в дерево?

   
 
 автор: tAleks   (11.12.2006 в 12:48)   письмо автору
 
   для: Trianon   (10.12.2006 в 21:50)
 

Загнал данные в массив:

    // Извлекаем все группы
    $sql = "SELECT name, code_group, code_parent, showhide FROM cms_groups";
    $query = mysql_query($sql);
    // если запрос не сделан, или сток извлечено < 1 возвращаем FALSE
    if(!$query || mysql_num_rows($query) < 1) return FALSE;
    // Запихиваем все в массив
    while ($k = mysql_fetch_assoc($query)) { $g[@++$i] = $k; }


Получился примерно такой масив:

    [15] => Array
        (
            [name] => Группа 2
            [code_group] => 16
            [code_parent] => 15
            [showhide] => show
        )

    [16] => Array
        (
            [name] => Группа 3
            [code_group] => 17
            [code_parent] => 16
            [showhide] => show
        )

    [17] => Array
        (
            [name] => Группа 4
            [code_group] => 18
            [code_parent] => 17
            [showhide] => show
        )

    [18] => Array
        (
            [name] => Группа 5
            [code_group] => 19
            [code_parent] => 18
            [showhide] => show
        )


Как теперь из него выстроить путь?

   
 
 автор: AlexelA   (12.12.2006 в 18:16)   письмо автору
 
   для: tAleks   (10.12.2006 в 19:21)
 

Возможно вам подойдет такой вариант:
Для начала определите первую, не скрытую группу.
Так как вы используете для хранения данных mysql, рекомендую
для поиска воспользоваться средствами mysql (скорость выполнения
скрипта будет выше).
Запрос примерно такой:

select name,max(code_group) from cms_groups where showhide='show';

Из результата запроса выбираете 'name' -имя последней не закрытой группы.
Для формирования строки меню, выводите имена групп до тех пор, пока
не дойдете до группы 'name' или группы в которой лежит статья, если номер
искомой группы "выше", чем 'name'.
Надеюсь идея понятна.

   
Rambler's Top100
вверх

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