PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (2): [1] 2 »   

> Описание: Помогите с реализацией условия
Saymor
Отправлено: 12 Июля, 2011 - 08:11:44
Post Id



Новичок


Покинул форум
Сообщений всего: 52
Дата рег-ции: Май 2011  


Помог: 0 раз(а)




вывод данных из БД в виде дерева

есть БД
| id |--------| parent |--------| name |
+----+--------+--------+--------+------------+
| 1 |--------| 0 |--------| Родитель 1 |
| 2 |--------| 0 |--------| Родитель 2 |
| 3 |--------| 0 |--------| Родитель 3 |
| 4 |--------| 0 |--------| Родитель 4 |
| 5 |--------| 0 |--------| Родитель 5 |
| 6 |--------| 0 |--------| Родитель 6 |
| 11 |--------| 1 |--------| Потомок 1 |
| 12 |--------| 1 |--------| Потомок 2 |
| 13 |--------| 2 |--------| Потомок 1 |
| 14 |--------| 13 |--------| Потомок 1 |
| 15 |--------| 13 |--------| Потомок 2 |

выводим данные из БД
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. // делаем запрос
  3. $cats = "SELECT id,name,parent FROM category";
  4.  
  5. // создаем многомерный массив
  6. $tree = array();
  7. for($i=0,$n=count($cats); $i<$n; $i++){
  8.  $cat = $cats[$i];
  9.         if(empty($tree[$cat->parent]))
  10.                 $tree[$cat->parent]=array();
  11.         $tree[$cat->parent][] = $cat;
  12. }
  13.  
  14. // вызываем рекурсивную функцию, передаём ей массив
  15.  ShowCategory($tree);
  16.  
  17. // создаём рекурсивную функцию
  18. function ShowCategory(&$tree,$k_parent=0){
  19.     if(empty($tree[$k_parent])) return;
  20.  
  21.     // выводим дерево
  22.     echo $k_parent ? "<ul>" : "";
  23.     for($i=0,$n=count($tree[$k_parent]); $i<$n; $i++){
  24.       echo "<li>";
  25.         if(??????? кое условие ?????????){ // здесь суть моего вопроса
  26.                 echo "<span>".$tree[$k_parent][$i]->name."</span>";
  27.         }else{
  28.             echo "<a href='index.php?category=".$tree[$k_parent][$i]->id."'>".$tree[$k_parent][$i]->p_name."</a>";
  29.         }
  30.  
  31.         // функция вызывает сама себя с массивом $tree и $tree[$k_parent][$i]->id родителя
  32.         ShowCategory($tree, $tree[$k_parent][$i]->id);
  33.       echo "</li>";
  34.     }
  35.     echo $k_parent ? "</ul>" : "";
  36. } ?>


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

(Отредактировано автором: 12 Июля, 2011 - 13:24:49)

 
 Top
DeepVarvar Супермодератор
Отправлено: 12 Июля, 2011 - 09:01:00
Post Id



Активный участник


Покинул форум
Сообщений всего: 10378
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Что-то типа:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM category ORDER BY id ASC GROUP BY parent
 
 Top
Saymor
Отправлено: 12 Июля, 2011 - 13:08:43
Post Id



Новичок


Покинул форум
Сообщений всего: 52
Дата рег-ции: Май 2011  


Помог: 0 раз(а)




DeepVarvar пишет:
Что-то типа:
CODE (SQL):
скопировать код в буфер обмена

SELECT * FROM category ORDER BY id ASC GROUP BY parent




спасибо, но это НЕ то....
Мне кажется модераторы перенесли тему не в ту степь!
Тема моего сообщения затрагивает "Рекурсию", а не БД!

(Отредактировано автором: 12 Июля, 2011 - 13:13:17)

 
 Top
OrmaJever Модератор
Отправлено: 12 Июля, 2011 - 13:46:42
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




нет тема какраз таки затрагивает бд. Вы просто изначально не верно написали.
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.  
  3. // вызываем рекурсивную функцию, передаём ей массив
  4.  ShowCategory(0);
  5.  
  6. // создаём рекурсивную функцию
  7. function ShowCategory($parent = 0){
  8.  
  9.          $q = mysql_query("SELECT id,name,parent FROM category WHERE parent = $parent");
  10.     if(mysql_num_rows($q) == 0) return;
  11.  
  12.     // выводим дерево
  13.     echo "<ul>";
  14.  
  15.     while($ob = mysql_fetch_object($q)) {
  16.       echo "<li>";
  17.       echo "<a href='index.php?category=".$ob->id."'>".$ob->name."</a>";
  18.       ShowCategory($ob->id);
  19.       echo "</li>";
  20.     }
  21.     echo "</ul>";
  22. }
  23. ?>

Вроде верно, но мог и гдето ошибится
(Добавление)
только что проверил


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Saymor
Отправлено: 12 Июля, 2011 - 13:59:35
Post Id



Новичок


Покинул форум
Сообщений всего: 52
Дата рег-ции: Май 2011  


Помог: 0 раз(а)




OrmaJever пишет:
нет тема какраз таки затрагивает бд. Вы просто изначально не верно написали.
PHP:
скопировать код в буфер обмена

<?PHP

// вызываем рекурсивную функцию, передаём ей массив
ShowCategory(0);

// создаём рекурсивную функцию
function ShowCategory($parent = 0){

$q = mysql_query("SELECT id,name,parent FROM category WHERE parent = $parent");
if(mysql_num_rows($q) == 0) return;

// выводим дерево
echo "<ul>";

while($ob = mysql_fetch_object($q)) {
echo "<li>";
echo "<a href='index.php?category=".$ob->id."'>".$ob->name."</a>";
ShowCategory($ob->id);
echo "</li>";
}
echo "</ul>";
}
?>


Вроде верно, но мог и гдето ошибится



хм. Ваш подход ведет к множеству запросов к БД, а это не приемлемо если у нас дерево неограниченной вложенности.
Мой код в начале темы делает всего 1 запрос к БД, далее работаем только с массивом, сортируя его так чтоб вышло дерево.. и все работает, вот только с условием беда...
с выводом ссылки конечного потомка
 
 Top
OrmaJever Модератор
Отправлено: 12 Июля, 2011 - 14:37:42
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Saymor пишет:
Ваш подход ведет к множеству запросов к БД

Да это так но не факт что с вариант с масивом будет лутше.
Цыкл который делает этот масив потянет время + если неограниченая вложеность то сам масив потянет большую память.


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Saymor
Отправлено: 12 Июля, 2011 - 14:54:52
Post Id



Новичок


Покинул форум
Сообщений всего: 52
Дата рег-ции: Май 2011  


Помог: 0 раз(а)




OrmaJever пишет:
Да это так но не факт что с вариант с масивом будет лутше.
Цыкл который делает этот масив потянет время + если неограниченая вложеность то сам масив потянет большую память.


ну даже не знаю что сказать!
в целом массив кэшировать можно, так же как и запросы к БД,,,,
Однако читал, что 1 запрос лучше. Не думаю что массив нагнет сервак больше чем множественные запросы к БД..

(Отредактировано автором: 12 Июля, 2011 - 14:55:47)

 
 Top
OrmaJever Модератор
Отправлено: 12 Июля, 2011 - 16:03:16
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Saymor пишет:
Однако читал, что 1 запрос лучше.

Да один запрос лутше чем много но смотря с чем сравнивать.
Saymor пишет:
Не думаю что массив нагнет сервак больше чем множественные запросы к БД

Это спорный вопрос и зависит от вложености.


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Saymor
Отправлено: 12 Июля, 2011 - 16:51:20
Post Id



Новичок


Покинул форум
Сообщений всего: 52
Дата рег-ции: Май 2011  


Помог: 0 раз(а)




OrmaJever пишет:
Это спорный вопрос и зависит от вложености.


думаю вложенность будет максимум 4 - 5 уровней
 
 Top
OrmaJever Модератор
Отправлено: 12 Июля, 2011 - 17:02:26
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Запросов много не будет. Вот для даного примера их будет всего 4
первый - красный
второй - зелёный
трейтий - синий
четвёртый - жолтый


Может ещё кто-то другой выскажет своё мнение по этому поводу Улыбка


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Мелкий Супермодератор
Отправлено: 12 Июля, 2011 - 17:08:32
Post Id



Активный участник


Покинул форум
Сообщений всего: 11874
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 612 раз(а)




OrmaJever, вообще-то 4 - это будет результатов.
А запросов будет 11. Без запроса не узнаешь, есть ли дочерние элементы.

Saymor, возможно, условие будет isset($tree[$id]), если я правильно понял исходник.


-----
PostgreSQL DBA
 
 Top
Саныч Модератор
Отправлено: 12 Июля, 2011 - 17:17:11
Post Id



Участник


Покинул форум
Сообщений всего: 1364
Дата рег-ции: Июль 2010  
Откуда: Украина, Запорожье


Помог: 62 раз(а)




OrmaJever пишет:
Может ещё кто-то другой выскажет своё мнение по этому поводу
А что тут высказывать, вы уже и так все растолковали...
Оба вариант имеют свои плюсы и свои минусы, и оптимального решения нет... Тут нужно выбирать меньшее зло... Исходя из задачи которую необходимо реализовать...

OrmaJever пишет:
Запросов много не будет. Вот для даного примера их будет всего 4
Не факт... Это смотря какая вложенность планируется и количество самих элементов... Пример из личного опыта: когда-то сделал знакомому менюшку на рекурсии. В итоге когда он все это дело наполнил, получилось, что местами вложенность достигала 6 - 7 уровня. В итоге - почти полсотни запросов к БД.

Saymor, если это что-то типа менюхи, то вначале выводите только родителей, а дальше уже аяксом подгружать потомков по кликам на родителей...
(Добавление)
Мелкий пишет:
Без запроса не узнаешь, есть ли дочерние элементы
а это и не нужно узнавать... Делается запрос на выборку элементов, а проверка наличия - по количеству выбраных результатов


-----
Все возражают против того, что я гений, хотя никто еще так меня не назвал. - Орсон Уэллс
 
 Top
Мелкий Супермодератор
Отправлено: 12 Июля, 2011 - 17:20:17
Post Id



Активный участник


Покинул форум
Сообщений всего: 11874
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 612 раз(а)




Саныч пишет:
Делается запрос на выборку элементов, а проверка наличия - по количеству выбраных результатов

А эт типа не запрос? Так, из астрала, тягаем данные?


-----
PostgreSQL DBA
 
 Top
Саныч Модератор
Отправлено: 12 Июля, 2011 - 17:25:46
Post Id



Участник


Покинул форум
Сообщений всего: 1364
Дата рег-ции: Июль 2010  
Откуда: Украина, Запорожье


Помог: 62 раз(а)




Это к тому, что
Цитата:
вообще-то 4 - это будет результатов.
А запросов будет 11
запросов тоже будет 4!


-----
Все возражают против того, что я гений, хотя никто еще так меня не назвал. - Орсон Уэллс
 
 Top
Мелкий Супермодератор
Отправлено: 12 Июля, 2011 - 17:30:14
Post Id



Активный участник


Покинул форум
Сообщений всего: 11874
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 612 раз(а)




Саныч, посыплю голову пеплом и признаю, что я дурак и делать мне в программировании нечего, если докажешь, что следующее неверно:
Представленный чуть ранее код OrmaJever'а делает запрос для каждого элемента списка. Сколько элементов - столько и запросов.

Рекурсивная функция осуществляет запрос и в цикле обхода результата вызывается рекурсивно => для каждого элемента производится запрос к базе.
Вот если бы было поле в записи родителя типа "у меня есть дети, смотри далее" и оно проверялось перед вызовом рекурсии - да, запросов было бы столько, сколько элементов имеют детей.

(Отредактировано автором: 12 Июля, 2011 - 17:33:37)



-----
PostgreSQL DBA
 
 Top
Страниц (2): [1] 2 »
Сейчас эту тему просматривают: 1 (гостей: 1, зарегистрированных: 0)
« Работа с СУБД »


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



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB