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

Форум PHP

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

 

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

вид форума:
Линейный форум (новые сообщения вниз) Структурный форум

тема: Алгоритм вложенности каталогов

Сообщения:  [1-10]   [11-17] 

 
 автор: Trianon   (31.05.2010 в 02:13)   письмо автору
 
   для: Diman   (30.05.2010 в 18:45)
 

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

  Ответить  
 
 автор: Diman   (30.05.2010 в 18:45)   письмо автору
 
   для: neadekvat   (30.05.2010 в 16:43)
 

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

function menu_nav( $id_parent,  $tabl )
 { 
 
    $query="SELECT * FROM ".$tabl." WHERE id_parent =".$id_parent." And  hide='show' ORDER BY pos ";
    $result=mysql_query($query);
      if(!$result)
 
       {
         echo  "Ошибка обращения к таблице каталога menu_navigation()";
       }
    
     if (mysql_num_rows($result) > 0)
      {

        echo("<ul >\n");

          while ( $row = mysql_fetch_array($result) )
           {
               $ID1 = $row["id_catalog"];
               echo("<li>\n");
               if (!$row['id_parent']){
                  echo  $row["name"];
               } else
               echo("<a  href=?link=2&id_catalog=".$ID1.">".$row["name"]."</a>"." \n");
               menu_nav($ID1,$tabl); 
          }
           
             echo("</ul>\n");
        }         
}
menu_nav(0,'articlecat');


А в таком коде какие будут предложения по улучшению?

  Ответить  
 
 автор: neadekvat   (30.05.2010 в 16:43)   письмо автору
 
   для: Trianon   (30.05.2010 в 15:35)
 

Наконец-то!) Я три месяца ждал, когда меня исправят (не в смысле, что я знал ответ, а в смысле, что не знал как реализовать лучшее решение)
Спасибо :)

  Ответить  
 
 автор: Trianon   (30.05.2010 в 15:35)   письмо автору
 
   для: neadekvat   (05.02.2010 в 22:26)
 

ну вот.
Классический пример лишней рекурсии.

Идею (даже не идею, а данность), что для формирования пути узел-корень нужен всего лишь цикл, я продвигаю здесь уже четвертый или пятый раз.
При чем последний - не позднее прошлой недели.
Очевидно, имеет смысл опять привести теоретическое обоснование.
функция вида
<?
function recursive() 

   
некие операторы;
   if(
некое_условие)  
       
recursive();
}

формально преобразуется к варианту
<?
function itterative()
{
   do 
   {
        
некие операторы;
   }
   while(
некое_условие);
}

если, конечно эти некие операторы сами по себе рекурсивного вызова не содержат.

Это теория.
Теперь практика.

Ваш код
<?
if(!$arr['parent_id'])   { // если родительской категории нет
  
return true;
  }  else  {
  
navigation($arr['parent_id']);
  } 

содержит лишний else, поскольку после return выполнение всё равно прекращено.
И лишние скобки, поскольку одиночные операторы в составной блок объединять смысл невелик.
А значит
<?
if(!$arr['parent_id']) 
  return 
true;  // если родительской категории нет
  
navigation($arr['parent_id']);


А с учетом того, что это последний код в функции - вызов можно поставить под условие напрямую:
<?
if($arr['parent_id']) 
  
navigation($arr['parent_id']); // если родительской категории есть
  
return true;  

А учитывая Ваш контекст, выйдет:
<?
function navigation($cat_id) {
 global 
$links;
 
$query mysql_query("SELECT * FROM cats WHERE id = $cat_id");
 
$arr mysql_fetch_assoc($query);
 
// $arr['id'] - id категории
 // $arr['parent_id'] - id родительской категории
 // $arr['name'] - имя категории
 
$links[] = array('name' => $arr['name'], 'id' => $arr['id']); // открытая категория
  
if($arr['parent_id']) 
    
navigation($arr['parent_id']); // если родительской категории есть
  
return true;  



Вот мы и пришли к каноническому виду для упразднения рекурсии.

<?
function navigation($cat_id
{
  global 
$links;
  do 
  {
    
$query mysql_query("SELECT * FROM cats WHERE id = $cat_id");
    
$arr mysql_fetch_assoc($query);
    
// $arr['id'] - id категории
    // $arr['parent_id'] - id родительской категории
    // $arr['name'] - имя категории
    
$links[] = array('name' => $arr['name'], 'id' => $arr['id']); // открытая категория
  
}
  while((
$cat_id $arr['parent_id']) != 0); // пока есть родительская категория



Заметьте, я выполнил преобразование, вообще не касаясь предметной области.
Просто как робот.

  Ответить  
 
 автор: diman   (30.05.2010 в 13:49)   письмо автору
 
   для: neadekvat   (05.02.2010 в 22:26)
 

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

Пробовал сам, у меня немного другие переменные, но это не суть важно.


$sql="Select * From articlecat Where hide='show'";
$ct=mysql_query($sql);
if(mysql_num_rows($ct)>0){
  while($cat = mysql_fetch_array($ct)){
    if (!$cat['id_parent']){
      //echo "<ul><a href=?link=2&id_catalog=".$cat['id_catalog'].">".$cat['name']."</a></ul>";
    }
    else {  
      navigation($cat['id_catalog']);
      krsort($links);
      foreach($links as $link) { 
        echo ' » <a href="?link=2&id_catalog=' . $link['id'] . '">' . $link['name'] . '</a>';
        $links = array();   
      } 
    }
    echo "<hr>";

  }
}


Но тогда пустые каталоги, без вложения, не будут видны. Чтобы это осуществить нужно переделать функцию navigation(), чтобы она вводила в массив $links только вложенные имена подрубрик. Как это осуществить? Или может что-нибудь получше предложите?

  Ответить  
 
 автор: class   (06.02.2010 в 00:22)   письмо автору
 
   для: neadekvat   (05.02.2010 в 23:59)
 

Пока я писал - вы уже написали о этой сортировке :)

Спасибо за помощь!

  Ответить  
 
 автор: neadekvat   (05.02.2010 в 23:59)   письмо автору
 
   для: class   (05.02.2010 в 23:50)
 

О чем я и сказал 4мя минутами раньше вас =)

  Ответить  
 
 автор: class   (05.02.2010 в 23:50)   письмо автору
 
   для: class   (05.02.2010 в 23:41)
 

Решил проблему сортировкой
krsort() вместо rsort()

  Ответить  
 
 автор: neadekvat   (05.02.2010 в 23:46)   письмо автору
 
   для: class   (05.02.2010 в 23:41)
 

Замените rsort() на krsort(), там же по ключам надо. Постоянно забываю.

  Ответить  
 
 автор: class   (05.02.2010 в 23:41)   письмо автору
 
   для: neadekvat   (05.02.2010 в 22:26)
 

Спасибо!
Вроде как работает, только тут что то с сортировкой массива.
Беспорядочно выводит навигацию при большой вложенности.


Вот добавлял в базу отрывок алфавита.

Вот так вывело:
Главная » Ё » А » Б » В » Г » Д » Е » Ж » З » И » К » Л » М » Н » О » П » Р » С » Т » У

  Ответить  

Сообщения:  [1-10]   [11-17] 

Форум разработан IT-студией SoftTime
Rambler's Top100
вверх

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