Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] menu wielopoziomowe - jak wyświetlić podkategorię w odpowiedniej kategorii?
Forum PHP.pl > Forum > Przedszkole
pafeu
witam
mam bazę danych
  1. INSERT INTO `categories` (`cat_id`, `parent_id`, `left_id`, `right_id`, `level`, `cat_name`, `sub_counter`, `counter`, `cat_colour`, `cat_image`) VALUES
  2. (1, -1, 1, 70, -1, 'All', 5, 0, '', ''),
  3. (214, 1, 18, 69, 0, 'KATEGORIA', 0, 0, '', ''),
  4. (223, 214, 19, 68, 1, 'PODKATEGORIA', 0, 0, '', ''),
  5. (224, 223, 66, 67, 2, 'POPDPODKATEGORIA', 0, 0, '', ''),

kategorie pobieram
  1. $query = "SELECT * FROM categories WHERE parent_id=1 ORDER BY left_id";
  2. $wynik = mysql_query($query);
  3. while ($row = mysql_fetch_assoc($wynik)) {
  4. echo $row['cat_name'] .' - - - ' ;
  5. }

podkategorie wyświetlam:
  1. $query = "SELECT * FROM categories WHERE parent_id>1 ORDER BY left_id";
  2. $wynik = mysql_query($query);
  3. while ($row = mysql_fetch_assoc($wynik)) {
  4. echo $row['cat_name'] .' - - - ' ;
  5. }

Jak połączyć ze sobą kategorie i podkategorie aby podkategoria wyświetlała się pod odpowiednią kategorią?
ghost1511
  1. <ul>
  2. <li>Kategoria
  3. <ul>
  4. <li>
  5. Podkategia
  6. </li>
  7. </ul>
  8. </li>
  9. </ul>


A tak całkiem serio to w czym masz problem? Bo wygląda na to, że już na etapie projektowania bazy popełniłeś błąd (nie przewidziałeś pewnej sytuacji).
pafeu
Cytat(ghost1511 @ 1.03.2014, 16:03:15 ) *
...już na etapie projektowania bazy popełniłeś błąd ...

... jaki błąd - co masz na myśli?
ghost1511
Zakładając że masz tylko parent_id a menu wielopoziomowe możesz pobrać wcześniej podmenu którego rodzica wcześniej nie pobrałeś np:
Kod
ID  PARENT_ID NAZWA
1   NULL          MENU
2   3              PODMENU2
3   1              PODMENU1


Taka sytuacja może się zdarzyć kiedy manipulujesz kolejnością, np najpierw utworzysz grupy a później przypiszesz ich rodziców. Do głowy przychodzą mi dwa rozwiązania: Dodanie jakiegoś parametru który będzie odpowiadał za kolejność np:

Kod
ID  PARENT_ID NAZWA       KOLEJNOSC
1   NULL          MENU          1
2   3               PODMENU2  3
3   1               PODMENU1  2


Ale wtedy musisz pilnować, aby nie wystąpiły jakieś konflikty typu powtórzenie (co możesz wymusić UNIQUE), by mieć pewność że wszystkie wartości są pobierane w odpowiedniej kolejności.

Lub sprawdzać czy rodzic danego rekordu był pobrany wcześniej jeżeli tak to przypisać podmenu lub jeżeli nie to przesunąć go na następną pozycję. Choć gdy to piszę ten pomysł wydaje się karkołomny i pierwsze rozwiązanie wydaje się być łatwiejsze.
pafeu
znalazłem takie rozwiązanie w necie
wydaje mi się że można zaadoptować do mojego przypadku
  1. <!--/*
  2. CREATE TABLE IF NOT EXISTS `menu_wielopoziomowe_1` (
  3. `id` int(11) NOT NULL auto_increment,
  4. `label` varchar(50) NOT NULL default '',
  5. `link_url` varchar(100) NOT NULL default '#',
  6. `parent_id` int(11) NOT NULL default '0',
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;
  9.  
  10. INSERT INTO `menu_wielopoziomowe_1` (`id`, `label`, `link_url`, `parent_id`) VALUES
  11. (1, 'MENU1', '', 0),
  12. (2, 'MENU2', '', 0),
  13. (3, 'podmenu1', ', 1),
  14. (4, 'podmenu1', '', 1),
  15. (5, 'podmenu2', '', 2),
  16. (6, 'podmenu2', '', 2),
  17. (7, 'MENU3', '', 0),
  18. (8, 'podmenu3', '', 7),
  19. (9, 'podmenu3', '', 7),
  20. */
  21. -->
  22. <?php
  23. $sql = "SELECT id, label, link_url, parent_id FROM menu_wielopoziomowe_1 ORDER BY parent_id, id ASC";
  24. $items = mysql_query($sql);
  25. while ($obj = mysql_fetch_object($items)) {
  26. if ($obj->parent_id == 0) {
  27. $parent_menu[$obj->id]['label'] = $obj->label;
  28. $parent_menu[$obj->id]['link'] = $obj->link_url;
  29. } else {
  30. $sub_menu[$obj->id]['parent'] = $obj->parent_id;
  31. $sub_menu[$obj->id]['label'] = $obj->label;
  32. $sub_menu[$obj->id]['link'] = $obj->link_url;
  33. if (!isset($parent_menu[$obj->parent_id]['count'])) {
  34. $parent_menu[$obj->parent_id]['count'] = 0;
  35. }
  36. $parent_menu[$obj->parent_id]['count']++;
  37. }
  38. }
  39.  
  40. function dyn_menu_nie_rozwijane($parent_array, $sub_array, $qs_val = "menu", $main_id = "nav", $sub_id = "subnav", $extra_style = "foldout") {
  41. $menu = "<ul id=\"".$main_id."\">\n";
  42. foreach ($parent_array as $pkey => $pval) {
  43. if (!empty($pval['count'])) {
  44. $menu .= " <li><a class=\"".$extra_style."\" href=\"".$pval['link']."?".$qs_val."=".$pkey."\">".$pval['label']."</a></li>\n";
  45. } else {
  46. $menu .= " <li><a href=\"".$pval['link']."\">".$pval['label']."</a></li>\n";
  47. }
  48. }
  49. $menu .= "</ul>\n";
  50. return $menu;
  51. }
  52. mysql_close($connection);
  53. ?>
  54.  
  55.  
  56. <?php
  57. echo dyn_menu_nie_rozwijane($parent_menu, $sub_menu, "menu", "nav", "subnav");
  58. ?>

próbowałem zmodyfikować ale mi nie chce działać
może ktoś pomoże?
smile.gif

?
Pyton_000
To Ci rozjaśni trochę umysł. To czego Ty używasz to Nested set

http://blog.mwojcik.pl/2008/02/17/drzewa-k...-php-metoda-ip/
YourFrog
Istnieją różne sposoby rozwiązania tego problemu w bazach pokroju MySQL (oracle chyba tylko nie ma z nimi problemów)
- Metoda depesza
- Metoda IP
- Metoda prawo-lewo
- Parent ID

Każda z metod ma zalety jak i wady i to którą zaimplementujesz do aktualnego projektu zależy od sytuacji. Osobiście najczęściej używam metody prawo-lewo w połączeniu z parent ID w celu szybkiej odbudowy.

Jeżeli chodzi o metodę prawo-lewo. To na tym >> blogu << pewna blogerka świetnie opisała ten sposób w 6 częściowym artykule.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.