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

Форум MySQL

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

 

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

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

тема: Из таблицы рубрик в дерево рубрик
 
 автор: Eugene77   (01.07.2009 в 19:36)   письмо автору
 
 

Есть таблица
CREATE TABLE rubrics(
id INT UNIQUE,
parent_id INT,
name VARCHAR
)


Задача:
Превратить, полученную одним запросом из базы данных таблицу, в иерархический массив.

Мне что-то в голову приходят только весьма ресурсоёмкие алгоритмы.
Есть соображения как оптимально построить такую функцию?

  Ответить  
 
 автор: Trianon   (01.07.2009 в 21:26)   письмо автору
 
   для: Eugene77   (01.07.2009 в 19:36)
 

<?
$tree 
= array();
$list = array();
while(
$row =  mysql_fetch_row($res))
{
    
$list[$row[0]] = array($row[1], $row[2]);
    
$tree[$row[1]][] = $row[0];
}

  Ответить  
 
 автор: Eugene77   (02.07.2009 в 19:00)   письмо автору
 
   для: Trianon   (01.07.2009 в 21:26)
 

Пока идеи не уловил.
Понял только, что зря я в структуре таблицы указал name.
Он там будет, конечно, и ещё некоторые поля будут,но они не связаны с иерархичностью. Поэтому, чтобы не путаться зря, давайте как будто структура таблицы вот такая:
CREATE TABLE rubrics( 
id INT UNIQUE, 
parent_id INT
)

  Ответить  
 
 автор: Trianon   (02.07.2009 в 19:15)   письмо автору
 
   для: Eugene77   (02.07.2009 в 19:00)
 

давайте.

  Ответить  
 
 автор: Eugene77   (03.07.2009 в 19:52)   письмо автору
 
   для: Trianon   (02.07.2009 в 19:15)
 

>давайте.

Спасибо, конечно, что вы разрешили, но посмотрите только что за ерунда у меня получается:
(вчера ночью, я что-то туда лишнее вписал. Вот что я имел в виду (ИСПРАВЛЕНО)):

<?php
class IE{
    private 
$ie=array();
    private 
$rubtic_names=array();
    private 
$items=array(); // table of aticles with reference to rubrics

    
private function one_level_seach($root$child$key, &$brench){
        If(
$root == $key){ // если такая ветка уже существует,просто добавим к ней нового потомка
            // if(isset( $this -> $brench[$child])) { echo "secondary entry"; return true;}
            
$new $brench + array($child => array());
            return 
$new;
        } 
// Если на этом уровне такой ветки нет, поищем на более "тонких" веточках
        
foreach($brench as $k =>$b) if($bb $this -> one_level_seach($root$child$k, &$b)) break;
        if(isset(
$bb)) if($bb) {
            if(!
is_array($bb)) return true//незначительная ошибка. Ничего не делаем
            
unset($brench[$k]);
            return 
$brench + array($k => $bb);
        }
        return 
false;
    }
    public function 
resorse2ie(&$resorse){
        while (
$l mysql_fetch_assoc($resorse)) {
            
$this -> rubric_names[$l['id_rubric']] = array( // образуем массив имён рубрик
            
"name" => $l['name'],
            
"icon" => $l['icon'],
            );
            
// Образуем иерархию рубрик
            
$child = (int)$l['id_rubric']; $parent = (int)$l['parent'];
            if(isset( 
$this -> ie[$child])) { // найден корень у того, что было  корнем
                
$this -> ie[$parent] = array($child => $this -> ie[$child]); // Присоединяем удлинённую ветку снова
                
unset($this -> ie[$child]); // Удаляем старую короткую ветку
                
continue;
            }
            
//  Рекурсивный обход всех веток в поисках этой рубрики
            
foreach($this -> ie as $k => $b) if($bb $this -> one_level_seach($parent$child$k, &$b)) break;
            if(isset(
$bb)) if($bb) {
                if(!
is_array($bb)) continue; //незначительная ошибка. Пропускаем запись (Повтор пары родитель-наследник)
                
$this -> ie[$k]=$bb;
                unset(
$bb);
                continue;
            }
            
// если нигде нет, то создаём новый корень
            
$this -> ie[$parent] = array($child => array());
        }
        return (
$this -> ie);
    }

    
}
require_once(
"config.inc");
$q "SELECT * FROM test.ie";
$rmysql_query($q) or exit("<br> $q <br>".mysql_error());
$ie = NEW IE;
$tree $ie -> resorse2ie(&$r);

print_r($tree);


?>

Как-то всё это очень уж бестолково выглядит!
Ну, а вообще-то - это мой первый класс в жизни.
Так что, пожалуйста, покритикуйте его.

И подскажите
1. как правильно оформлять такие классы?
2. Какой алгоритм может быть эффективнее?
3. Почему-то на вот эту строку:
<?
if(isset( $this -> $brench[$child]))

сыплются замечания. А как тогда определять, установлено ли значение переменной? Что-то никак не разберусь я с объектно ориентированным подходом : (
На всякий случай, если будет время протестировать, добавляю пример дампа таблицы:
--
-- Структура таблицы `ie`
--

CREATE TABLE IF NOT EXISTS `ie` (
  `num` int(4) unsigned NOT NULL auto_increment,
  `id_rubric` int(10) unsigned NOT NULL default '0',
  `parent` int(10) unsigned NOT NULL default '0',
  `name` varchar(40) NOT NULL,
  `icon` varchar(40) NOT NULL,
  PRIMARY KEY  (`num`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 COMMENT='Иерархия рубрик' AUTO_INCREMENT=6 ;

--
-- Дамп данных таблицы `ie`
--

INSERT INTO `ie` (`num`, `id_rubric`, `parent`, `name`, `icon`) VALUES
(1, 2, 1, 'первый корень', ''),
(2, 3, 1, 'второй корень', ''),
(3, 33, 3, 'первая ветка от 2 ветки', ''),
(4, 333, 33, 'первая ветка от 3 ветки', ''),
(5, 334, 33, 'вторая ветка от 3 ветки', '');

  Ответить  
 
 автор: Eugene77   (05.07.2009 в 16:01)   письмо автору
 
   для: Trianon   (02.07.2009 в 19:15)
 

Такой страшенный код получается потому что адрес ветки, который я передаю при вызове рекурсивной функции почему-то не позволяет мне модифицировать исходную ветку.
Те изменения, которые я делаю в рекурсивной функции,почему-то не передаются массиву из которого ссылка взята.
А может, я как всегда, что-то путаю.
А может, это такой прикол в ООП и надо делать как-то иначе.
В общем - запутался

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

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