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

Форум PHP

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

 

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

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

тема: Оптимизация
 
 автор: Assessor   (28.09.2008 в 13:56)   письмо автору
 
 

Добрый день.
С точки зрения работоспособности работает на ура, строит правильные списки <ul><li>, нареканий нет, но такое ощущение, что я перемудрил, и есть гораздо проще решение, поэтому прошу взглянуть трезвым взглядом. Во первых не нравиться запрос в цикле, он больше всех и раздражает.... Во вторых, просто не нравиться, громоздко слишком.


Таблицы
// NESTED SETS (категории)
| id | parent_id | name | tree_left | tree_right | tree_level |
// Страницы
| id | cat_id | name | sort |

// Сама функция построения списков
function ISMmenu()
{
    global $dbInit, $settings_table;

    $retMenu    = '';
    $menu        = '';

    // Считываем какое меню у нас установлено
    $query_menu = "
            SELECT pos_menu
                FROM " . $settings_table['settings_menu'] . "
                ORDER BY    id
                LIMIT        1
                ";
    if ($row_menu = $dbInit -> get_row($query_menu))
    {
        $current_level = 0;

        $pos_menu        = $row_menu -> pos_menu;

        $query_cat = "
                SELECT *
                    FROM " . $settings_table['page_cat'] . "
                    ORDER BY        parent_id, tree_left
                    ";
        if ($rows_pageCat = $dbInit -> get_results($query_cat))
        {
            $retMenu .= '<ul id = "navDropTopMenu">';

            foreach ($rows_pageCat as $row_pageCat)
            {
                $cat_id        = intval($row_pageCat -> id);
                $cat_name    = '<a href = "">' . htmlspecialchars_decode($row_pageCat -> name) . '&nbsp;&#187;</a>';
                $tree_left    = intval($row_pageCat -> tree_left);
                $tree_right    = intval($row_pageCat -> tree_right);
                $tree_level    = intval($row_pageCat -> tree_level);

                if ($tree_level === $current_level)
                {
                    $retMenu .= '<li>' . $cat_name;
                }
                else if ($tree_level > $current_level)
                {
                    $retMenu .= '<ul><li>' . $cat_name;
                    $current_level++;
                }


                $query_page = "
                        SELECT id, link, name
                            FROM " . $settings_table['pages'] . "
                            WHERE        approved        = 'Yes'
                            AND            cat_id            = " . $cat_id . "
                            ORDER BY    sort
                            ";
                if ($rows_page = $dbInit -> get_results($query_page))
                {
                    if ($tree_level === $current_level)
                    {
                        $retMenu .= '<ul>';
                    }

                    foreach ($rows_page as $row_page)
                    {
                        $id            = intval($row_page -> id);
                        $name        = htmlspecialchars_decode($row_page -> name);

                        if ($tree_level < $current_level)
                        {
                            $menu = '<ul><li><a href = "#">' . $name . '</a></li></ul>';
                        }
                        else
                        {
                            $retMenu .= '<li><a href = "#">' . $name . '</a></li>';
                        }
                    }

                    if ($tree_level === $current_level)
                    {
                        $retMenu .= '</ul>';
                    }
                }

                if ($tree_level === $current_level && $tree_right - $tree_left === 1)
                {
                    $retMenu .= '</li>';
                }
                else if ($tree_level < $current_level)
                {
                    $retMenu .= '</ul></li><li>' . $cat_name . $menu . '</li>';
                    $current_level--;
                }
            }

            $retMenu .= '</ul>';
        }
    }
    else
    {
        return LANG_ERROR_NOMENUPOS;
    }

    return $retMenu;
}

  Ответить  
 
 автор: Trianon   (28.09.2008 в 14:12)   письмо автору
 
   для: Assessor   (28.09.2008 в 13:56)
 

Вообще-то метод NESTED SETS ориентирован в первую очередь на то, чтобы выборку дерева (в порядке обхода в глубину) можно было делать одним единственным SQL-запросом.

  Ответить  
 
 автор: Assessor   (28.09.2008 в 14:17)   письмо автору
 
   для: Trianon   (28.09.2008 в 14:12)
 

Я с этим и не спорю... Я ж говорю, не могу построить валидный спискок "<ul>" одним запросом....

  Ответить  
 
 автор: mihdan   (28.09.2008 в 14:22)   письмо автору
 
   для: Assessor   (28.09.2008 в 13:56)
 

[поправлено модератором]

  Ответить  
 
 автор: Assessor   (28.09.2008 в 14:29)   письмо автору
 
   для: mihdan   (28.09.2008 в 14:22)
 

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

  Ответить  
 
 автор: mihdan   (28.09.2008 в 14:41)   письмо автору
 
   для: Assessor   (28.09.2008 в 14:29)
 

Вы статью прочтите, посмотрите ссылки внизу ее - все есть только читать нужно.
Загляните сюда

  Ответить  
 
 автор: Assessor   (28.09.2008 в 18:08)   письмо автору
 
   для: mihdan   (28.09.2008 в 14:41)
 

но... вы сами смотрели класс который работает с NESTED SETS деревьями? и понимаете что я делаю в коде? думаете, я вот так взял и написал, не пошарив при этом инет? вы мне пальцем ткните, а то я уже чувствую себя ущербным, не видя очевидные вещи

  Ответить  
 
 автор: Trianon   (28.09.2008 в 19:12)   письмо автору
 
   для: Assessor   (28.09.2008 в 18:08)
 

А как эти самые <li> и <ul> должны расставляться?
Я тут попробовал набросать скрипт вывода списка, но понял, что расстановка самих тегов для меня - темный лес.
Пример бы. Аргументированный.

  Ответить  
 
 автор: Trianon   (28.09.2008 в 20:01)   письмо автору
 
   для: Trianon   (28.09.2008 в 19:12)
 

Набросал черновик, который выводит нечто напоминающее то, что строит word.

<?php
   
require_once('dbconfig.php');
function 
tab($s) { return "\r\n".str_repeat(' '2*count($s)); }
function 
drop($x,$s)
{
    for(
$v ''; !empty($s) && $x $s[$t count($s)-1]; $v .= tab($s)."</ul>")
      unset(
$s[$t]);
    return 
$v;
}
$sql "SELECT * FROM dirtree ORDER BY lb ";
$res=mysql_query($sql) or exit("Error in $sql " mysql_error());
for(; 
$row mysql_fetch_assoc($res); )
{
    echo 
drop($lb intval($row['lb']), &$s);
    echo 
tab($s)."<li>"htmlspecialchars($row['name']). "</li>";
    if(
$lb+< ($rb=intval($row['rb'])))
    {
        echo 
tab($s)."<ul>";
        
$s[] = $rb;
    }
}
echo 
drop($s[0]+1,&$s);

?>


PS1. В примере таблица с полями name, lb, rb
lb и rb - соответственно левая и правая границы поддерева. Вообще-то никакие другие ключи для вывода NESTED SETS не требуются.
PS2. tab() - чисто для красоты вывода. Ничего, кроме пробелов, она не вычисляет.

  Ответить  
 
 автор: Assessor   (29.09.2008 в 07:50)   письмо автору
 
   для: Trianon   (28.09.2008 в 20:01)
 

Мой гибрид из Nested Sets и списков смежности, строит многоуровневое выпадающее меню.
На выходе получается примерно такой код
<ul>
<li>Тест1
<ul>
<li>Тест1.1
<ul>
<li>Тест1.1.1</li>
</ul>
</li>
<li>Тест1.2
</li>
</ul>
</li>
<li>Тест2

</li>
</ul>

  Ответить  
 
 автор: Trianon   (29.09.2008 в 10:40)   письмо автору
 
   для: Assessor   (29.09.2008 в 07:50)
 

так тоже можно. Три строки изменить.
<?php
   
require_once('dbconfig.php');
function 
tab($s) { return "\r\n".str_repeat(' '2*count($s)); }
function 
drop($x,$s)
{
    for(
$v ''; !empty($s) && $x $s[$t count($s)-1]; $v .= tab($s)."</ul></li>")
      unset(
$s[$t]);
    return 
$v;
}
$sql "SELECT * FROM dirtree ORDER BY lb ";
$res=mysql_query($sql) or exit("Error in $sql " mysql_error());
for(; 
$row mysql_fetch_assoc($res); )
{
    echo 
drop($lb intval($row['lb']), &$s);
    echo 
tab($s)."<li>"htmlspecialchars($row['name']);
    if(
$lb+< ($rb=intval($row['rb'])))
    {
        echo 
tab($s)."<ul>";
        
$s[] = $rb;
    } else echo  
"</li>";
}
echo 
drop($s[0]+1,&$s);

?>

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

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