Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамическое, древовидное меню. PHP-скрипт. 
:(
    Опции темы
qsajeal
Дата 14.8.2008, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.8.2008

Репутация: нет
Всего: нет



Здравствуйте! У меня следующая проблема:
У меня есть каталоги неограниченной вложенности:
таблица categ содержит поля:
с_id (первичный ключ)
pc_id (первичный ключ родительской категории)
таблица articles содержит поля:
a_id
c_id(первичный ключ категории в которой находится статья)
-----
Причем в категории могут быть как другие категории, так и  статьи
----

Нужно написать скрипт, который будет динамически формировать древовидное меню в виде списка(беря данные из бд, которые естетвенно меняются постоянно), а этот список уже с помощью одного
плагина jQuery преобразуется в древовидное меню
Пример списка:
<li><span class="folder">Folder 1</span>
                        <ul>
                                <li><span class="file">Item 1.1</span></li>
                                <li><span class="file">Item 1.2</span></li>
                                <li><span class="file">Item 1.3</span></li>
                                <li><span class="file">Item 1.4</span></li>
                                <li><span class="file">Item 1.5</span></li>
                        </ul>
                </li>
                <li class="closed"><span class="folder">Folder 2</span>
                        <ul>
                                <li><span class="folder">Subfolder 2.1</span>
                                        <ul id="folder21">
                                                <li><span class="file">File 2.1.1</span></li>
                                                <li><span class="file">File 2.1.2</span></li>
                                                <li><span class="file">File 2.1.3</span></li>
                                                <li><span class="file">File 2.1.4</span></li>
                                                <li><span class="file">File 2.1.5</span></li>
                                                <li><span class="file">File 2.1.6</span></li>
                                                <li><span class="file">File 2.1.7</span></li>
                                        </ul>
                                </li>

Я уже 2 дня думаю как это сделать.
Вот если бы уровень вложенности был известен, то легко. А универсального решения найти не могу. 
ПОМОГИТЕ МНЕ ПОЖАЛУЙСТА.
Задача ведь действительно интересная и решение может часто использоваться.
PM MAIL   Вверх
solenko
Дата 14.8.2008, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 2
Всего: 67



qsajeal, а вы нопишите для вложенности, скажем..., 3. А потом мы уже будем смотреть как ваш скрипт переделать.
*с вашей структурой базы обычно используется рекурсивная функция.

Ну и так, на всякий случай, про другие методы хранения деревьев можно почитать поуглив materialized path или Nested Sets



--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
qsajeal
Дата 14.8.2008, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.8.2008

Репутация: нет
Всего: нет



Код

$query="SELECT name, c_id FROM categ WHERE pc_id=NULL";
$qd=mysql_query ($query);
while ($t=mysql_fetch_row($qd)){

<li>
$t[0]

$query1="SELECT name, c_id FROM categ WHERE pc_id=".$t[1]."";

while($t=mysql_fetch_row($qd)){


<li>

$t[0]

...

Даже на примере первой директории. И так до бесконечности...
PM MAIL   Вверх
gEndelf
Дата 14.8.2008, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 7.7.2005
Где: the world

Репутация: нет
Всего: 3



а ты не задумывался - сколько запросов к базе будет ?  smile 
в Oracle есть иерархические запросы, в MySQL с этим сражаются другим оружием )

Сцылка 1 

ну и погугли - по запросу "Mysql hierarhical queries"
PM MAIL WWW   Вверх
solenko
Дата 14.8.2008, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 2
Всего: 67



я тут пофантазировал на счет того как это все за лдин запрос выбрать...
Код

<?php
$tree = array(
    array(1, 'item1', null),
    array(2, 'item2', null),
    array(3, 'item3', null),
    array(4, 'item4', null),
    array(5, 'item2.1', 2),
    array(6, 'item2.2', 2),
    array(7, 'item2.3', 2),
    array(8, 'item2.2.1', 6),
    array(9, 'item2.2.2', 6),
    array(25, 'item2.2.2.1', 9),
);

function normolize($arr) {
    $tree = array();
    foreach ($arr as $node) {
        $tree[array_shift($node)] = $node;
    }
    foreach($tree as $key => &$node) {
        if ($node[1]) {
            if (!isset($tree[$node[1]]['childs'])) {
                $tree[$node[1]]['childs'] = array();
            }
            $tree[$node[1]]['childs'][$key] = &$node;
            $node['is_child'] = true;
        }else{
            $node['is_child'] = false;
        }
    }
    return $tree;   
}

var_dump(normolize($tree));



--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
qsajeal
Дата 14.8.2008, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.8.2008

Репутация: нет
Всего: нет



А как это теперь сделать, чтобы списком выводило?
PM MAIL   Вверх
Anarki
Дата 14.8.2008, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 14.3.2005

Репутация: 1
Всего: 11



Использованы данные и функция выше.
Вообще тут простейшая рекурсия.
Код

outTree(normolize($tree),0,true);
function outTree($tree,$tabs = 0,$firstrun = false) {
    $shiftConstant = 4;
    $nameOfChildIndex = 'childs';
    $shift = '';
    $shiftInternal = '';
    if (!$firstrun) {
       $shift = str_pad($shift,$tabs,' ');
    }
    $shiftInternal = str_pad($shift,$tabs+$shiftConstant,' ');
    echo $shift.'<ul>'."\n";
    foreach ($tree as $k=>$v) {
        if (isset($v[$nameOfChildIndex])) {
            echo $shiftInternal.'<li><span class="folder">'.$v[0]."</span>\n";
            outTree($v[$nameOfChildIndex],$tabs+$shiftConstant*2);
            echo $shiftInternal.'</li>'."\n";
        } else { // просто элемент без чайлдов
            echo $shiftInternal.'<li><span class="file">'.$v[0].'</span></li>'."\n";
        }
    }
    echo $shift.'</ul>'."\n";
}

На выходе такая красота
Код

<ul>
    <li><span class="file">item1</span></li>
    <li><span class="folder">item2</span>
        <ul>
            <li><span class="file">item2.1</span></li>
            <li><span class="folder">item2.2</span>
                <ul>
                    <li><span class="file">item2.2.1</span></li>
                    <li><span class="folder">item2.2.2</span>
                        <ul>
                            <li><span class="file">item2.2.2.1</span></li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li><span class="file">item2.3</span></li>
        </ul>
    </li>
    <li><span class="file">item3</span></li>
    <li><span class="file">item4</span></li>
    <li><span class="file">item2.1</span></li>
    <li><span class="folder">item2.2</span>
        <ul>
            <li><span class="file">item2.2.1</span></li>
            <li><span class="folder">item2.2.2</span>
                <ul>
                    <li><span class="file">item2.2.2.1</span></li>
                </ul>
            </li>
        </ul>
    </li>
    <li><span class="file">item2.3</span></li>
    <li><span class="file">item2.2.1</span></li>
    <li><span class="folder">item2.2.2</span>
        <ul>
            <li><span class="file">item2.2.2.1</span></li>
        </ul>
    </li>
    <li><span class="file">item2.2.2.1</span></li>
</ul>


Это сообщение отредактировал(а) Anarki - 14.8.2008, 22:50


--------------------
PM WWW   Вверх
qsajeal
Дата 15.8.2008, 05:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.8.2008

Репутация: нет
Всего: нет



А зачем он выводит все папки сразу, как сделать, чтобы только Item 1-4?
PM MAIL   Вверх
qsajeal
Дата 15.8.2008, 06:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.8.2008

Репутация: нет
Всего: нет



Ну наступил некоторый прогресс smile 
Я понял как работает функция normolize!!!
Теперь понял как выводится дерево.
Теперь вопрос: Как остановить рекурсию на стадии когда закончится обход тех пунктов, которые лежат в null???
PM MAIL   Вверх
qsajeal
Дата 15.8.2008, 07:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.8.2008

Репутация: нет
Всего: нет



Я сделал. Просто нужно было оказываетс удалить все элементы ненужные из нормализованного массива:
Код

foreach ($tree as $k=>$v){
        If (!empty($v['is_child'])) { unset($tree[$k]);   }



}


Теперь надо подумать, как это связать с таблицей статей? 

PM MAIL   Вверх
qsajeal
Дата 15.8.2008, 07:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.8.2008

Репутация: нет
Всего: нет




Подскажите пожалуйста как сделать??? smile 
Я могу конечно внести в этот же массив все данные из таблицы articles, но мне нужно сохранить id этих статей, чтобы потом ссылки делать.
PM MAIL   Вверх
solenko
Дата 15.8.2008, 07:58 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 2
Всего: 67



Цитата(qsajeal @  15.8.2008,  04:16 Найти цитируемый пост)
А зачем он выводит все папки сразу, как сделать, чтобы только Item 1-4?

Затем, что имнно такой вопрос вы задавали в начале темы

Добавлено через 2 минуты и 31 секунду
Цитата(qsajeal @  15.8.2008,  06:57 Найти цитируемый пост)
Подскажите пожалуйста как сделать???  Я могу конечно внести в этот же массив все данные из таблицы articles, но мне нужно сохранить id этих статей, чтобы потом ссылки делать.

У меня не было вашей тпблицы, поэтому массив записан в исходнике. Что мешает передать в normolize
результат mysql_fetch_assoc?

Скрипт, который я привел, не предназначен для практического использования. Два скрипта в теме -- просто пример, опираясь на который нужно сделать решение, подходящее вам.


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
Boxa
Дата 1.11.2008, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 25.10.2006

Репутация: -2
Всего: -2



рекурсия. 1 таблица id, idp, text. Можно все сделать через JavaScript, но это еще геморнее smile
PM MAIL   Вверх
Zmiuko
Дата 9.11.2008, 02:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


http://zmiuko.ru
**


Профиль
Группа: Участник
Сообщений: 297
Регистрация: 8.10.2008

Репутация: нет
Всего: 2



Вопрос такой, почему функция normolize выводит

Код

<ul>
    <li><span class="file">item1</span></li>
    <li><span class="folder">item2</span>
        <ul>
            <li><span class="file">item2.1</span></li>
            <li><span class="folder">item2.2</span>
                <ul>
                    <li><span class="file">item2.2.1</span></li>
                    <li><span class="folder">item2.2.2</span>
                        <ul>
                            <li><span class="file">item2.2.2.1</span></li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li><span class="file">item2.3</span></li>
        </ul>
    </li>
    <li><span class="file">item3</span></li>
    <li><span class="file">item4</span></li>
    <li><span class="file">item2.1</span></li>
    <li><span class="folder">item2.2</span>
        <ul>
            <li><span class="file">item2.2.1</span></li>
            <li><span class="folder">item2.2.2</span>
                <ul>
                    <li><span class="file">item2.2.2.1</span></li>
                </ul>
            </li>
        </ul>
    </li>
    <li><span class="file">item2.3</span></li>
    <li><span class="file">item2.2.1</span></li>
    <li><span class="folder">item2.2.2</span>
        <ul>
            <li><span class="file">item2.2.2.1</span></li>
        </ul>
    </li>
    <li><span class="file">item2.2.2.1</span></li>
</ul>


где последние

Код

...
   <li><span class="file">item2.1</span></li>
    <li><span class="folder">item2.2</span>
        <ul>
            <li><span class="file">item2.2.1</span></li>
            <li><span class="folder">item2.2.2</span>
                <ul>
                    <li><span class="file">item2.2.2.1</span></li>
                </ul>
            </li>
        </ul>
    </li>
    <li><span class="file">item2.3</span></li>
    <li><span class="file">item2.2.1</span></li>
    <li><span class="folder">item2.2.2</span>
        <ul>
            <li><span class="file">item2.2.2.1</span></li>
        </ul>
    </li>
    <li><span class="file">item2.2.2.1</span></li>
</ul>


являются лишними, поскольку уже были выведены и как это исправить?
PM MAIL WWW ICQ Skype Jabber   Вверх
evilsoul
Дата 9.11.2008, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 31.3.2006

Репутация: нет
Всего: 0



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

Это сообщение отредактировал(а) evilsoul - 9.11.2008, 19:25
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса

Внимание: данный раздел предназначен для решения сложных, нестандартных задач.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Для профи | Следующая тема »


 




[ Время генерации скрипта: 0.1088 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.