Welcome to PHPClub
В эти выходные на LinuxFest v.12! Поляна от PHPClubа Мастер-классы по Javascript, AJAX/COMET, jQuery!
Боишься нашего дизайна?
поиск:
   
 Начало | Настройки | Расширенный поиск | РегистрацияПосмотреть новые сообщения 
  
PHP Club форумы: > Вопросы по программированию на РНР > Вопросы по теории программирования > Загрузка данных из БД ввиде дерева.
Страниц (4): [1] 2 3 4 » |  

Автор
Тема ОТВЕТИТЬ
riff
Новичок

На форуме с: Feb 2007
Cообщений: 73
Город:
Загрузка данных из БД ввиде дерева.

Оцените, пожалуйста, код (Загрузка данных из БД ввиде дерева.). Не очень строго, т.к. учусь.
<?php
/**
 * PHP 4.4.4
 *
 * БД
 * -----
 * ID - Идентификатор ветки
 * PID - Родительский ID (если pid=0 значит это самая первая ветка)
 * FIELD1, FIELD2,... - Поля таблицы
 * -----
 *
 * @return array
 */
function &make_tree()
{
    
$tree = array();

    
$query mysql_query('select * from `my_table` order by `field2`');
    if (! 
$query) return $tree;

    
$nodes = array();
    
$keys = array();
    while ((
$node mysql_fetch_assoc($query)))
    {
        
//if ($node['childs'] === '1') //если есть поле определяющее наличие дочерних веток
        //    $node['nodes'] = array();  //то добавляем к записи узел (массив дочерних веток) на данном этапе
        
$nodes[$node['id']] =& $node//заполняем список веток записями из БД
        
$keys[] = $node['id']; //заполняем список ключей(ID)
        
unset($node);
    }
    
mysql_free_result($query);

    foreach (
$keys as $key)
    {
        
/**
         * если нашли главную ветку(или одну из главных), то добавляем
         * её в дерево
         */
        
if ($nodes[$key]['pid'] === '0')
            
$tree[] =& $nodes[$key];

        
/**
         * else находим родительскую ветку и добавляем текущую
         * ветку к дочерним элементам родит.ветки.
         */
        
else
        {
            if (isset(
$nodes$nodes[$key]['pid'] ])) //на всякий случай, вдруг в базе есть потерянные ветки
            
{
                if (! isset(
$nodes$nodes[$key]['pid'] ]['nodes'])) //если нет поля определяющего наличие дочерних веток
                    
$nodes$nodes[$key]['pid'] ]['nodes'] = array(); //то добавляем к записи узел (массив дочерних веток) на данном этапе

                
$nodes$nodes[$key]['pid'] ]['nodes'][] =& $nodes[$key];
            }
        }
    }
    return 
$tree;
}

$tree =& make_tree();
print_r($tree);
?>

Old Post 03.04.07 09:06 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
Alexandre
Edocs.phpclub.net

На форуме с: Mar 2002
Cообщений: 5005
Город: Saint Petersburg, Russia

 
Оцените, пожалуйста, код


оценить алгоритм или стиль кода?

с точки зрения архитектуры кода, использую
- классы доступа к БД.
- использую классы в принципе,
в общем ООП инфицированный.

вообще смысл этой функции, ну загрузили дерево из БД,
а дальше - опять обход дерева, но уже в массиве ?

Отредактировано Alexandre 03.04.07 в 09:14

Old Post 03.04.07 09:10 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
riff
Новичок

На форуме с: Feb 2007
Cообщений: 73
Город:

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

Old Post 03.04.07 09:14 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
HEm
Сетевой бобер

На форуме с: Sep 2000
Cообщений: 1093
Город: Наб. Челны, Россия

Alexandre
вопрос был не про твои предпочтения


__________________
Бобры добры, козлы злы!

Old Post 03.04.07 09:14 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
Фанат
oncle terrible

На форуме с: Jul 2003
Cообщений: 33516
Город: Broomfield, United States

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

оно у тебя вообще работает? при какой вложенности?

Old Post 03.04.07 09:15 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
riff
Новичок

На форуме с: Feb 2007
Cообщений: 73
Город:

*****
Да, конечно, всё проверил и перепроверил.

>>при какой вложенности?
Ннесколько веток в которых несколько подветок, в тех тоже несколько подветок.

Old Post 03.04.07 09:27 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
HEm
Сетевой бобер

На форуме с: Sep 2000
Cообщений: 1093
Город: Наб. Челны, Россия

проверил на своем каталоге товаров, не сработало
$tree выходит пустое, а вот $nodes почти то что нужно, только там дерево со ВСЕМИ ветками, для 7770 товаров имхо, скрипту вполне может наступить кирдык по памяти

-~{}~ 03.04.07 12:39:

ах, ну да, у меня нет ветки с pid=0, поторопился с выводами, все работает


__________________
Бобры добры, козлы злы!

Old Post 03.04.07 09:33 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
riff
Новичок

На форуме с: Feb 2007
Cообщений: 73
Город:

 
Автор оригинала: HEm
проверил на своем каталоге товаров, не сработало $tree выходит пустое


это потому, что, наверно, у тебя нет ветки(ок) у которой PID = 0, именно она(и) попадает(ют) в tree.
 
только там дерево со ВСЕМИ ветками, для 7770 товаров имхо, скрипту вполне может наступить кирдык по памяти


По памяти, если все товары влезли в массив, не наступит, т.к. добавление дочерних элементов происходит не путём копирования, а через указатели.

-----
а как у тебя со скоростью (в смысле не заполнения массива из базы данных, а после строки mysql_free_result) ?

Отредактировано riff 03.04.07 в 09:42

Old Post 03.04.07 09:40 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
Фанат
oncle terrible

На форуме с: Jul 2003
Cообщений: 33516
Город: Broomfield, United States

HEm
вы говорите о разном.
он говорит о структуре каталога, а ты - о его содержимом.

Old Post 03.04.07 09:41 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
HEm
Сетевой бобер

На форуме с: Sep 2000
Cообщений: 1093
Город: Наб. Челны, Россия

В общем, тут вместо рекурсии используются указатели, и оно работает, оригинально.

__________________
Бобры добры, козлы злы!

Old Post 03.04.07 09:46 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
riff
Новичок

На форуме с: Feb 2007
Cообщений: 73
Город:

 
Автор оригинала: Alexandre ?
а дальше - опять обход дерева, но уже в массиве ?


Ну, всё таки подход-то к решению задачи несколько иной, нежели, к примеру, рекурсия.

Old Post 03.04.07 09:52 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
Alexandre
Edocs.phpclub.net

На форуме с: Mar 2002
Cообщений: 5005
Город: Saint Petersburg, Russia

я не про рекурсию,

если ты имеешь 7 700 товаров, а в некоторых бахах их и до 100 000 бывает, то тебе нет необходимости их все затаскивать в массив, для того, чтоб отобразить ветку из 25 позиций.

пять лет назад я разбирал в бинарное дерево используя двухпроходной алгоритм (синтактический анализ и Си).

Здесь сделано нечно похоже.
Использование указателя вместо рекурсии - это плюс.

Отредактировано Alexandre 03.04.07 в 10:38

Old Post 03.04.07 10:35 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
Фанат
oncle terrible

На форуме с: Jul 2003
Cообщений: 33516
Город: Broomfield, United States

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

Old Post 03.04.07 10:36 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
HEm
Сетевой бобер

На форуме с: Sep 2000
Cообщений: 1093
Город: Наб. Челны, Россия

Давайте уже резюмируйте и перенесем топик в теорию?

__________________
Бобры добры, козлы злы!

Old Post 03.04.07 10:41 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
riff
Новичок

На форуме с: Feb 2007
Cообщений: 73
Город:

 
Автор оригинала: Alexandre
тебе нет необходимости их все затаскивать в массив, для того, чтоб отобразить ветку из 25 позиций.


Я в своём примере расчитывал только на то, что ты(<абстрактно) вытащил селектом (в данном случае всё) ни больше ни меньше.
---
Пока писал ответ, меня уже опередили

Old Post 03.04.07 10:42 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
serglt
Анус, ой, Ахтунг

На форуме с: Dec 2005
Cообщений: 229
Город:

Не плохой алгоритм формирования дерева без рекурсии
Решил попробовать вывести дерево без рекурсии, и вот что у меня получилось:

//--- Данные ---
    
$treeData = array (
        array (
            
'title'   => 'Auto&Moto',
            
'chields' => array (
                array (
                    
'title' => 'auto',
                    
'chields' => array (
                        array (
'title' => 'Vaz'),
                        array (
'title' => 'Gaz'),
                        array (
'title' => 'Zil'),
                    )
                ),
                array (
                    
'title' => 'moto',
                    
'chields' => array (
                        array (
'title' => 'Izh'),
                        array (
'title' => 'Dnepr'),
                        array (
'title' => 'Ural'),
                    )
                ),
            )
        )
    );

//--- Вывод ---
    
$nbspCnt 0;
    
$curPos 0;
    
$tree = &$treeData;
    
$count  count ($tree);
    
$stateArray = array ();
    do {
        while (
$curPos $count) {
            echo 
str_repeat ('&nbsp;&nbsp;&nbsp;'$nbspCnt) . $tree [$curPos] ['title'] . "<br>";
            if (isset (
$tree [$curPos] ['chields'])) {
                
array_push ($stateArray, array ('tree' => &$tree'count' => $count'curPos' => $curPos 1));
                
$tree = &$tree [$curPos] ['chields'];
                
$count count ($tree);
                
$curPos 0;
                
$nbspCnt ++;
            } else {
                
$curPos ++;
            }
        }
        if ((
$a array_pop ($stateArray)) !== null) {
            
$curPos $a ['curPos'];
            
$count  $a ['count'];
            
$tree   $a ['tree'];
            
$nbspCnt --;
        }
    } while (
$a != null);

Old Post 03.04.07 14:35 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
Vallar_ultra
Любитель выпить :)

На форуме с: Jul 2005
Cообщений: 595
Город: Moscow, Russia

serglt
И где ты такие данные хранить собираешся( в таком виде имеется ввиду ) ?

Old Post 16.04.07 11:42 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
avenger_msoft
Новичок

На форуме с: Feb 2005
Cообщений: 59
Город: Pskov, Russia

riff

Похожая функция есть здесь

Отредактировано avenger_msoft 17.04.07 в 05:45

Old Post 17.04.07 05:07 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
riff
Новичок

На форуме с: Feb 2007
Cообщений: 73
Город:

avenger_msoft
Да, видимо что-то похожее...

code:
по поводу действительно ли функция, в моём первом сообщении, написана мной - даю честное слово, что она полностью придумана мной, и кроме как с помощью рекурсии я не знал как построить дерево. Поводом же к поиску другого способа было желание избавиться от десятков "лишних" циклов. Промежуточными результатами были доп.массивы с ключами-идентификаторами, доп.функции и т.п., которые(промежуточные результаты) и трансформировались в исходный результат.

Отредактировано riff 17.04.07 в 08:37
Old Post 17.04.07 07:52 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
serglt
Анус, ой, Ахтунг

На форуме с: Dec 2005
Cообщений: 229
Город:

Vallar_ultra
Если ты не заметил - это уже дерево, может оно быть и другогой структуры - это не принципиально, я просто вывел без рекурсии в браузер/консоль.

Old Post 17.04.07 12:59 URL сообщения | инфо об авторе | жалоба | IP: Записан | редактировать | ОТВЕТИТЬ и ЦИТИРОВАТЬ
Время GMT. Текущее время 23:13. Подписаться на Тему | Версия для Печати
Страниц (4): [1] 2 3 4 » |  

PHP Club форумы: > Вопросы по программированию на РНР > Вопросы по теории программирования > Загрузка данных из БД ввиде дерева.
 
Оценить:
 
 
 
 

 © 1997-2010 PHPClubTeam      

Powered by vBulletin Copyright © 2000-2010 Jelsoft Enterprises Limited.