Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php]/[mysql]/[js] jak zrobić wielopoziomowe kategorie produktow i menu do ich obsługi
Forum PHP.pl > Forum > Przedszkole
noels
Witam exclamation.gif


Pisze skrypt sklepu internetowego, zależy mi na tym aby sklep obsługiwał wielopoziomowe kategorie tzn np:

SPRZĘT AGD ---|
.......................|-miksery
.......................|-pralki---|
.....................................|-ładowane od góry
.....................................|-ładowane od przodu


mój pomysł na tabele w bazie odpowiedzialna za przechowywanie informacji o kategoriach jest następujący:

  1. CREATE TABLE kategorie
  2. (id_kategorii int UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
  3. id_kategorii_nadrzednej int UNSIGNED NOT NULL,
  4. nazwa char(100) NOT NULL,
  5. opis text NOT NULL);


tabela przechowujaca informacje o produktach:

  1. CREATE TABLE produkty
  2. (id_produktu int UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
  3. id_producenta int UNSIGNED NOT NULL,
  4. id_kategorii int UNSIGNED NOT NULL,
  5. id_stawki_vat int UNSIGNED NOT NULL,
  6. nazwa char(100) NOT NULL,
  7. numer_katalogowy char(15) NOT NULL,
  8. opis text NOT NULL,
  9. widoczny tinyint(1) UNSIGNED NOT NULL,
  10. nowosc tinyint(1) UNSIGNED NOT NULL,
  11. cena double(7,2) UNSIGNED NOT NULL,
  12. waga int(2) UNSIGNED NOT NULL,
  13. zdjecie char(50));


problem pojawia sie przy próbie stworzenia menu ktore takze musi byc wielopoziomowe, a przedewszystkim dynamiczne
tzn. musi tworzyc sie automatycznie na podstawie informacji pobranych z bazy danych.
Udało mi się znaleźć pewne gotowe menu lecz nie potrafie poradzić sobie z jego
tworzeniem na podstawie automatycznie pobranych informacji z bazy.

kod menu i jego dokładny opis znajduje się pod adresem MENU

nie będę go tu wklejał bo jest dosyć obszerny.

Problem tkwi w napisaniu skryptu który wygeneruje kod korzystając z informacji zapisanych w bazie wg wzoru:

  1. <dl id="menu0">
  2. <dt>Sprzęt AGD</dt>
  3. <dd>
  4. <dl>
  5. <dt>Miksery</dt>
  6. <dt>Pralki</dt>
  7. <dd>Ładowane od góry</dd>
  8. <dd>Ładowane od przodu</dd>
  9. </dl>
  10. </dd>
  11. </dl>


Domyślam się że trzeba skorzystać z jakiś pętelek lecz nie mam pojęcia jak to zrobić.

Może macie jakieś inne pomysły na strukture bazy bądź też samego menu chodzi mi poprostu aby
udało mi się napisać skrypt sklepu z wielopoziomowymi kategoriami i menu do ich przeglądania.

Z góry dziękuję za wszelkie porady.
yaotzin
A tak zastanawiam się czy nie można by robić tak aby w bazie określać głębokość menu. Np. 0 1 2 itp. wówczas będziesz wiedział że 0 jest na samej górze a 1 jest dzieckiemm rodzica o wartości 0 natomiast 2 dzieckiem rodzica o wartosci 1. Pozwoli ci to później nawet na zamienianie pozycji dynamicznie przenoszenie z jednego do drugiego itp. a jeśli chcesz aby to było dodatkowo menu rozwijane to sądzę że nie jest to trudne już po tym jak je wygenerujesz korzystając z PHP. Użyj JS i może CSS visibility: none; itp. smile.gif Więcej niż powyższe nie mogę ci pomóc, ale też za jakiś czas będę musiał napisać taki skrypt i powyższe mi wg projektu działa. ale... :/ zawsze może być lub jest jakieś ale...
noels
Dziekuje za zainteresowanie i podsuniecie swojej koncepcji, przeanalizowałem to co napisałes i doszedlem do pewnych wnioskow mianowice.

Wyglad tabeli wypelnionej danymi przy moim zalozeniu:

TABELA KATEGORIE

------------------------------------------------------------------
|id_kategorii|id_kategorii_nadrzednej|nazwa |opis|
------------------------------------------------------------------
|1 |0 |SPRZĘT AGD| |
|2 |1 |MIKSERY | |
|3 |1 |PRALKI | |
|4 |3 |Ład od góry | |
|5 |3 |Ład od przod| |
------------------------------------------------------------------

Wygląd tabeli wypełnionej danymi przy twoim założeniu:

TABELA KATEGORIE

------------------------------------------------------------------
|id_kategorii|glebokosc_menu |nazwa |opis|
------------------------------------------------------------------
|1 |0 |SPRZĘT AGD| |
|2 |1 |MIKSERY | |
|3 |1 |PRALKI | |
|4 |2 |Ład od góry | |
|5 |2 |Ład od przod| |
------------------------------------------------------------------

do tego momentu jest ok ale jezeli postanowimy dodac jeszcze chocby jeden poziom zerowy np. SPRZET RTV ktory bedzie poczatkiem nowego drzewka u Ciebie wystapi problem bo kategoria SPRZET RTV przyjmie glebokosc "0" i jezeli dodamy jej jakas podkategorie np: TELEWIZORY i ta podkategoria przyjmie zgodnie z Twoim zalozeniem wartosc glebokosc = "1" skad bedziemy wiedziec kogo dzieckiem sa MIKSERY, PRALKI, TELEWIZORY czy sa to dzieci SPRZETU AGD czy RTV u mnie taki problem nie wystapi bo kategoria SPRZET RTV przyjmie id_kategorii = 6, id_kategorii nadrzednej = 0 a jej dzieci przyjma kolejne id_kategorii natomiast id_kategorii_nadrzednej beda przyjmowac = 6 i bedzie wiadomo czyimi sa dziecmi.

Widze ze nawet moja koncepcja mogla by dzialac ale jak wygenerowac dla niej menu questionmark.gif? to jest dla mnie problem....

Tam pod tym linkiem prowadzacym do strony z MENU o którym wspominam jest naprawde dobry opis i wg niego mozna tworzyc nieskonczone struktury i glebokosci ja przedstawiajac tu schemat zawezilem go do 1 poziomu 0 st, 2 poziomow 1 st i 2 poziomow 2 stopnia ale mozna je dowolnie rozbudowywac moze jesli przeczytasz to pomoze Ci to w wymysleniu czegoas aby mi pomoc generalnie problem lezy napisaniu skryptu generujacego takich pare znacznikow HTML wg ponizszego schematu

  1. <dl id="menu0">
  2. <dt>Nagłówek 1</dt>
  3. <dd>
  4. <dl>
  5. <dt>Nagłówek 1.1</dt>
  6. <dd>
  7. <dl>
  8. <dt>Nagłówek 1.1.1</dt>
  9. <dd>Element 1.1.1.1</dd>
  10. <dd>Element 1.1.1.2</dd>
  11. <dd>Element 1.1.1.3</dd>
  12. <dt>Nagłówek 1.1.2</dt>
  13. <dd>Element 1.1.2.1</dd>
  14. <dd>Element 1.1.2.2</dd>
  15. <dd>Element 1.1.2.3</dd>
  16. </dl>
  17. </dd>
  18. <dt>Nagłówek 1.2</dt>
  19. <dd>Element 1.2.1</dd>
  20. <dd>Element 1.2.2</dd>
  21. <dd>Element 1.2.3</dd>
  22. </dl>
  23. </dd>
  24. <dt>Nagłówek 2</dt>
  25. <dd>
  26. <dl>
  27. <dt>Nagłówek 2.1</dt>
  28. <dd>Element 2.1.1</dd>
  29. <dd>Element 2.1.2</dd>
  30. <dd>Element 2.1.3</dd>
  31. <dt>Nagłówek 2.2</dt>
  32. <dd>Element 2.2.1</dd>
  33. <dd>Element 2.2.2</dd>
  34. <dd>Element 2.2.3</dd>
  35. </dl>
  36. </dd>
  37. </dl>

Jezeli zle mysle co do Twojej koncepcji, prosze popraw mnie. Moze wspolnie cos wymyslimy Tobie z tego co piszesz tez bedzie potrzebne takie rozwiazanie.
__mK
takie cos napisalem na studioceramica.pl

łap klase ktora moze Ci sie przydac (dowolna ilosc podkategorii- rekurencyjnie w takim porzadku jak ty opisales)

  1. <?php
  2. class mapa_strony {
  3.  
  4. public $ile=0;
  5.  
  6. function pobierzKategorie() {
  7.  
  8. }
  9.  
  10. function pobierzMenu($id) {
  11. $_pobierzKategoria = mysql_query("SELECT * FROM `menu` WHERE `IdMenu`='".$id."';");
  12. $_pokazKategorie = mysql_fetch_array($_pobierzKategoria);
  13.  
  14. if ($id!=-1) {
  15. $this->ile=$this->ile+1;
  16. return $this->pobierzMenu($_pokazKategorie['Podmenu']);
  17. }
  18. }
  19.  
  20. function pokazMenu() {
  21. $_pobierzKategorie = mysql_query("SELECT * FROM `menu`;");
  22. while ($_pokazKategorie = mysql_fetch_array($_pobierzKategorie)) {
  23. $efekt="";
  24. $this->pobierzMenu($_pokazKategorie['IdMenu']);
  25. for ($i=0;$i<=$this->ile;$i++) {
  26. $efekt .= ">>";
  27. }
  28. echo $efekt." ".$_pokazKategorie['NazwaM'].$_pokazKategorie['IdMenu']."<br />";
  29. $this->ile=0;
  30. }
  31. }
  32. }
  33.  
  34. $cos = new mapa_strony;
  35. $cos->pokazMenu();
  36. ?>
flv
Nie radziłbym korzystać z takich rozwiązań jak podał poprzednik, albo mi sie zdaje albo przy każdym pobraniu kategorii nadrzednych będzie także zapętlać się dodatkowe mysql_query dla tych podrzędnych, co za tym idzie jeśli będziesz chcial wyświetlić 3 kategorie i do każdej 3 podkategorie to wywołanych zostanie 10 zapytań, czyli lepiej nie mowić co by było jeśli tych kategorii podkategorii i kolejnych drzew było więcej. Można to zrobić jednym zapytaniem korzystając z LEFT/RIGHT JOIN'a.
noels
Dziękuję za klase ... muszę teraz to przeanalizować bo ja nigdy nie używałem klas i zastanowic sie nad tym w razie problemow pozwole sobie zapytac Cie o niezrozumiale dla mnie rzeczy.

Odpowiedz mi jeszcze tylko czy ta klasa bedzie odpowiednia dla mojej struktury tabeli przechowujacej informacje o kategoriach ? czy powinienem pomyslec o innej strukturze ?



Sprobowalem to przeanalizowac ale nie rozumiem niestety jest to chyba zbyt skomplikowane jak na moj obecny poziom wiedzy.

Jezeli moglbys mi pomoc w dostosowaniu tego do moich potrzeb czyli napisania funkcji do generowania takiego kodu jaki wzor zamiescilem wczesniej na podstawie mojej struktury bazy bede wdzieczny.

Nie oczekuje na gotowca, lecz proszę o pomoc, chcialbym wykorzystac menu ktore prezentowalem wczesniej z moja struktura tabeli. Oczywiscie widzialem menu ktore zamieszczales na stronie ktorej adres podales i zasada dzialania jest dokladnie taka jaka jest mi potrzebna wiec rozumiemy sie o co mi chodzi.
__mK
bedzie smigac jesli bedziesz mial cos takiego np

  1. CREATE TABLE `kategoria` (
  2. `IdK` int(11) NOT NULL AUTO_INCREMENT,
  3. `NazwaK` text character SET utf8,
  4. `PodKategoria` int(11) DEFAULT NULL,
  5. PRIMARY KEY (`IdK`)
  6. );


W tej klasie jest takie cos:
$efekt .= ">>";
zamiast tego musisz dodac jakis kod html
bo w tym przypadku bedzie wyswietlalo:

kat1
>>subkat1
>>subkat2
>>>>subsubkat1
>>>>>>subsubkat1
>>>>>>subsubkat2
>>>>subsubkat2
>>>>>>subsubkat1
>>subkat3

etc...
noels
Utworzyłem taka tabele jak pokazales, pozmienialm nazwy pol w klasie i niestety nie moge jej uruchomic... :-( poprostu caly czas sa bledy. Obawiam sie ze pomimo tego ze bardzo mi na tym zalezy nie poradze sobie z tym.

Ciezko jest z kawalka wyrwanego kodu cos osiagnac bo nawet nie wiem za bardzo co tam sie dzieje w tej klasie, ja zawsze robilem wszystko na samych funkcjach nie stosowalem nigdy klas widocznie nie doszedlem do tego stopnia zaawansowania.

Kilka pytan

1. Czemu wyskakuje blad w lini public $ile=0; nastepujacej tresci:

Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in c:\www\test.php on line 8

2. Gdzie tu jest miejsce na dokonanie polaczenia z baza danych ?

3. Po co funkcja function pobierzKategorie() skoro jest ona pusta ?
__mK
Zamiast public daj var bo public wystepuje w php 5 a ty moze masz starsza wersje php

aha i oczywiscie przed stworzeniem obiektu tej klasy polacz sie z baza... d;

ps kategorie ktore sa najwyzej w drzewie maja id = -1
noels
Naprawde nie mam pojecia jak uruchomic ten skrypt nie dziala mi poprostu nic...

Zrobilem tabele wg zalecen tzn:

  1. CREATE TABLE `kategorie2`
  2. ( `IdK` int(11) NOT NULL AUTO_INCREMENT, `NazwaK` text, `PodKategoria` int(11) DEFAULT NULL, PRIMARY KEY (`IdK`));



Dane w tabeli:

  1. inser INTO kategorie2 VALUES('1', 'Sprzet AGD', '-1');
  2. inser INTO kategorie2 VALUES('2', 'Pralki', '0');
  3. inser INTO kategorie2 VALUES('2', 'Lodówki', '0');


Skrypt wygląda następująco:

  1. <?
  2. $serwer="localhost";
  3. $uzytkownik="root";
  4. $haslo="krasnal";
  5. $nazwa_bazy="sklep";
  6.  
  7. function polacz()
  8. {
  9. global $serwer;
  10. global $uzytkownik;
  11. global $haslo;
  12. global $nazwa_bazy;
  13.  
  14. @ $baza=mysql_connect("$serwer", "$uzytkownik", "$haslo");
  15.  
  16. if (!$baza)
  17. {
  18. echo "brak polaczenia";
  19. }
  20.  
  21. mysql_select_db("$nazwa_bazy");
  22.  
  23. class mapa_strony
  24. {
  25. var $ile=0;
  26.  
  27. function pobierzKategorie()
  28. { }
  29.  
  30. function pobierzMenu($id)
  31. {
  32. $_pobierzKategoria = mysql_query("SELECT * FROM `kategorie2` WHERE `IdK`='".$id."';");
  33. $_pokazKategorie = mysql_fetch_array($_pobierzKategoria);
  34. if ($id!=-1)
  35. {
  36. $this->ile=$this->ile+1;
  37. return $this->pobierzMenu($_pokazKategorie['PodKategoria']);
  38. }
  39. }
  40.  
  41. function pokazMenu()
  42.  
  43. {
  44. $_pobierzKategorie = mysql_query("SELECT * FROM `kategorie2`;");
  45. while ($_pokazKategorie = mysql_fetch_array($_pobierzKategorie))
  46. {
  47. $efekt="";
  48. $this->pobierzMenu($_pokazKategorie['IdK']);
  49. for ($i=0;$i<=$this->ile;$i++)
  50. {
  51. $efekt .= ">>";
  52. }
  53.  
  54. echo $efekt." ".$_pokazKategorie['NazwaK'].$_pokazKategorie['IdK']."<br />";
  55. $this->ile=0;
  56. }
  57. }
  58. }
  59.  
  60. $cos = new mapa_strony;$cos->pokazMenu();
  61. ?>


Aha i jeszcze jedno a na jakiej zasadzie rozróżnisz jesli np: dwa poziomy najwyzsze czyli powiedzmy AGD i RTV i kazdy z nich bedzie mial osobne podkategorie, ktore podkategorie naleza do ktorego rodzica RTV czy AGD ?

Prosze pomóż bo nie moge ruszyc z miejsca lub podpowiedz jak skonstruowac petle aby dalo sie to zrobic na mojej zaproponowanej tabeli i aby uzyskac taki krotki kod html jak opisywany wczesniej
__mK
  1. inser INTO kategorie2 VALUES('1', 'Sprzet AGD', '-1');
  2. inser INTO kategorie2 VALUES('2', 'Pralki', '0');
  3. inser INTO kategorie2 VALUES('2', 'Lodówki', '0');


kolejno -1 0 0 to id kategorii nadrzednych
czyli jesli pralki i lodowki maja byc sub kategoriami Sprzed AGD to te pola powinny byc 1 1 (tak jak ma sprzet AGD)
noels
czyli taki układ

  1. INSERT INTO kategorie2 VALUES('1', 'Sprzet AGD', '-1');
  2. INSERT INTO kategorie2 VALUES('2', 'Pralki', '1');
  3. INSERT INTO kategorie2 VALUES('3', 'Lodówki', '1');
  4. INSERT INTO kategorie2 VALUES('4', 'Sprzęt RTV', '-1');
  5. INSERT INTO kategorie2 VALUES('5', 'TV', '4');
  6. INSERT INTO kategorie2 VALUES('6', 'LCD', '5');
  7. INSERT INTO kategorie2 VALUES('7', 'CRT', '5');
  8. INSERT INTO kategorie2 VALUES('8', 'Białe', '7');
  9. INSERT INTO kategorie2 VALUES('9', 'Czarne', '7');


Rozumiem :-) teraz oczywiscie działa, postaram sie dostosowac to do generowania takiego kodu jaki jest mi potrzebny w razie problemow pozwole sobie zwrocic sie do Ciebie z dalszymi pytaniami.

potrzebuje uzyskac nastepujaca postac kodu:

  1. <dl id="menu0">
  2. <dt>Nagłówek 1</dt>
  3. <dd>
  4. <dl>
  5. <dt>Nagłówek 1.1</dt>
  6. <dd>
  7. <dl>
  8. <dt>Nagłówek 1.1.1</dt>
  9. <dd>Element 1.1.1.1</dd>
  10. <dd>Element 1.1.1.2</dd>
  11. <dd>Element 1.1.1.3</dd>
  12. <dt>Nagłówek 1.1.2</dt>
  13. <dd>Element 1.1.2.1</dd>
  14. <dd>Element 1.1.2.2</dd>
  15. <dd>Element 1.1.2.3</dd>
  16. </dl>
  17. </dd>
  18. <dt>Nagłówek 1.2</dt>
  19. <dd>Element 1.2.1</dd>
  20. <dd>Element 1.2.2</dd>
  21. <dd>Element 1.2.3</dd>
  22. </dl>
  23. </dd>
  24. <dt>Nagłówek 2</dt>
  25. <dd>
  26. <dl>
  27. <dt>Nagłówek 2.1</dt>
  28. <dd>Element 2.1.1</dd>
  29. <dd>Element 2.1.2</dd>
  30. <dd>Element 2.1.3</dd>
  31. <dt>Nagłówek 2.2</dt>
  32. <dd>Element 2.2.1</dd>
  33. <dd>Element 2.2.2</dd>
  34. <dd>Element 2.2.3</dd>
  35. </dl>
  36. </dd>
  37. </dl>


Biorę się więc do pracy.


Bardzo dziękuje za pomoc i poświecony czas
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.