ugrás a tartalomhoz

Dinamikus ul - li mysql php

black_lagoon · 2008. Nov. 5. (Sze), 14.58
Sziasztok!

Saját lapom fejlesztgetése közben egy ( számomra ) érdekes problémába ütköztem és nem nagyon találtam rá megoldást, legalábbis olyat amit fel is tudnék fogni :)
A szitu a következő:
- adott egy mysql tábla : id, parent_id, name
- ebből kellene ul li listát készitenem egy menühöz egy rekurzív függvénnyel

Ha valakinek van tippje pls help, merre induljak el...

Köszi a tippeket...
 
2

Egy példa

deadcode · 2008. Nov. 5. (Sze), 15.35
Egy példa, nem is biztos, hogy működik, csak kb így néz ki egy rekurzív függvény:

function listRecursive($parent)
{
   $result = mysql_query('
      SELECT id, name
      FROM tabla
      WHERE parent_id = '.(int) $parent
   );
   // ide valami sql hibakezeles, nem ez a lenyeg most, de legyen! :)
   
   if (mysql_num_rows($result) < 1)
   {
      // ha nincs olyan elem, aminel ez a szulo, akkor semmit se kell csinalnunk
      return;
   }
   
   echo '<ul>';
   while ($row = mysql_fetch_assoc($result))
   {
      // kiirjuk az elem nevet, ha vannak "gyerekei", az kulon listaba megy moge
      echo '<li>'.$row['name'];
      /**
       * A lenyeg itt van, mindig az aktualis elemre futtatjuk ujra ezt a
       * fuggvenyt, de ott mar ez lesz a szulo elem, es igy tovabb.
       */
      listRecursive($row['id']);
      echo '</li>';
   }
   echo '</ul>';
}


Nyilván ha használsz PDO-t vagy egyéb DB layert, akkor máshogy néz ki a queryzés és az iteráció, ha nem közvetlenül kiírni szeretnéd a dolgokat, akkor az is máshogy fog kinézni, nulla HTML formázás a HTML forráskódban (indent/wrap), stb. A rekurzív működés lényegét viszont ebből szerintem át lehet látni.

EDIT: az elfelejtettem, hogy ha a gyökértől szeretnéd a listázást kezdeni, akkor listRecursive(0); használandó, tehát parent 0-ról indul, a db-ben remélhetőleg a gyökérbe szánt elemeknek 0 a parent_id-je.
1

Épp nemrég csináltam ilyet!

Ustak · 2008. Nov. 5. (Sze), 15.30
Volt egy weblap ami sokat segített, de nem találom már sajnos. No mindegy, én valami ilyet csináltam belőle:

private function menu($parent = 0) {
		$items=$this->query("SELECT id, parent_id, nev from termekek where parent_id=".(int)$parent." order by nev");
		?> <ul><?php
		while ($sor = $this->f_arr($items)) { //ez a fetch_array
			?><li><a id="<?php echo $id;?>" ><?php echo htmlspecialchars($sor['nev']); ?></a><?
		$this->menu($sor['id']);
		?></li><?php			
		}		
		?>
		  </ul>
		<?php

	}

Picit leszűkítettem, de a lényeg szerintem látszik.
Annyit szólnék még hozzá, amit az oldalon is elmondanak, hogy érdemes cache -elni valamilyen módon a menüt, mert ha sok, akkor ne minden index kérésnél írja ki (forduljon az adatbázishoz), hanem például csak akkor, ha változott a menü, mondjuk új menüpontot vettek fel vagy töröltek. Tehát ilyenkor generálsz egy statikus index.html-t a dinamikus index.php-ből (én legalábbis így csináltam) és a látogatóknak a statikus html-t érnék el.
3

erőforrás-pazarlás

gex · 2008. Nov. 5. (Sze), 16.07
a rekurzió ebben az esetben teljesen felesleges. mindkét példa erősen erőforrás-pazarló.
4

hmm alternatív megoldás?

deadcode · 2008. Nov. 5. (Sze), 16.22
Hogy lehet rekurzió nélkül ilyen formában tárolt adatokat listázni?
5

weblabor cikkek

gex · 2008. Nov. 5. (Sze), 16.29
Hierarchikus adatkezelés SQL-lel PHP-ben I.
Hierarchikus adatkezelés SQL-lel PHP-ben II.

ha viszont csak főmenü- és almenüpontok vannak akkor ez még túlzás is.
6

hawaii, dj, pálmafák, királyság

black_lagoon · 2008. Nov. 5. (Sze), 17.01
Először is köszi a tippeket!

deadcode kódja alapján megoldottam a problémát ( gyakorlatilag csak a db select-et kellett a saját cuccomhoz igazitani ), nagyon köszönöm! Viszont érdekelne ( ha más nem tanulás szempontjából ) a rekurzió nélküli dolog is, nem látom át hogyan lehetne megoldani a nélkül, bár ez valószínűleg rookie szintem miatt van... Köszi a segítséget!
7

Rekurzió

black_lagoon · 2008. Nov. 5. (Sze), 17.09
Végigolvastam napokkal ezlőtt ezt a cikket, Függőségi modell - nél is rekurzív fv-t használ ezért gondoltam hogy jó lesz, a cikk második részében ( Hierarchikus adatkezelés SQL-lel PHP-ben II. ) meg már kicsit bonyolultabb nekem a dolog, kicsit beletört a bicskám, ezért választottam az első megoldást. Köszi még 1X az infókat.
8

NP

deadcode · 2008. Nov. 5. (Sze), 18.21
A felvetett problémában a függőségi modellnek megfelelő struktúrában voltak tárolva az adatok, amit rekurzívan listázni milliós nagyságrend alatt nem okoz komoly gondot. Az alapvető probléma, hogy az elemeknél az egyetlen információ, hogy melyik a szülő elem, ami alatt található. Ez a függőségi modell, ha az adatoknál a szint is meg lenne határozva, ahol találhatók, vagy valami egyéb extra információ is lenne, nyilván nem biztos, hogy a klasszikus rekurzív működésre (és a minden elemnél queryzésre) szükség lenne, de gondolom nem tervezed, hogy átrendezd a struktúráját az adatoknak. :) Esetleg legközelebb már a tervezésnél lehet a bonyolultabb (de hatékonyabb) mintából kiindulni, de ilyen párszázas tétel még egy agyonterhelt szervernek se okoz gondot. Nem tudom ugyan, mennyi sorod van, de gondolom nem tízezerekről van szó. Ha ez a helyzet, akkor ne aggódj a hatékonyság miatt. ;)
10

milliós nagyságrend

gex · 2008. Nov. 5. (Sze), 18.58
1000 főkategória 1000 alkategóriája az pont 1001 lekérdezés. ez nem okoz komoly terhelést tényleg.
11

Adatbázis kezelő

zila · 2008. Nov. 6. (Cs), 13.43
Jobb adatbázisok ezt egy lekérdezéssel visszaadják neked... Másrészről 1000 főkategória és 1000 alkategóriát hogyan tálalsz a usernek? Ha egybe kilököd neki egy treeview-ba megvadul. Én biztos megvadulnék :)
12

ezt nekem?

gex · 2008. Nov. 6. (Cs), 14.24
se a feladatot nem én találtam ki, se a milliós nagyságrendet. az pedig, hogy ha 1000 mysql_query-t futtatok külön-külön, hogyan adja vissza egy "jobb adatbázis" nagyon érdekelne.
13

higalom, nyugavér

zila · 2008. Nov. 6. (Cs), 15.22
oracle-ben például így tudsz lekérdezni egy egyszerű szűlő-gyerek kapcsolatos szerkezetet:
select 
  lpad(' ', (level - 1) * 2) || name as padded_name, 
  slave_id, 
  supervisor_id, 
  level
from corporate_slaves
connect by prior slave_id = supervisor_id
start with slave_id = 1;
forrás

Ez 1 db lekérdezés, nem 1000*1000...

Csak azért neked válaszoltam, mert te mondtad, hogy 1000 mysql_query-t kell futtatni, mysql-ben lehet, de nem csak mysql létezik. Gondoltam jelzem, hogy van alternatíva, beszélgetünk, nem támadlak, ne védekezz :)
16

szerintem

gex · 2008. Nov. 6. (Cs), 21.00
Csak azért neked válaszoltam, mert te mondtad, hogy 1000 mysql_query-t kell futtatni, mysql-ben lehet, de nem csak mysql létezik.

elhangzott egy megoldás - ami történetesen mysql-t használt - és erre írtam, hogy ez erőforrás-pazarló. amikor az volt a válasz hogy nem - mindenféle indoklás nélkül -, akkor írtam hogy szerintem meg de, 1001 darab mysql_query az pazarló. ha szerinted még mindig teljesen relevánsan válaszoltál nekem, akkor bocs.
14

na ide hogy jutottunk?

deadcode · 2008. Nov. 6. (Cs), 16.22
A kérdés eredetileg arra irányult, hogy ebben a struktúrában tárolt adatokat hogy listázzunk rekurzívan, nem volt szó róla, hogy almenü-főmenü kell csak, vagy hogy optimalizáljuk nagy terhelésre/adathalmazra, úgyhogy nem értem, most mi a probléma. Igen, van más, hatékonyabb módszer is az adatok hierarchikus struktúrában tárolására/lekérdezésére, de szerintem ne lőjünk ágyúval verébre.
15

Mert programozók vagyunk :)

zila · 2008. Nov. 6. (Cs), 17.24
Azért jutottunk el ide mert programozók vagyunk, számbaveszünk minden eshetőséget és a legrosszabra készülünk fel :)
17

te vetetted fel

gex · 2008. Nov. 6. (Cs), 21.02
ha nem dobálózol olyanokkal, hogy milliós nagyságrendig semmi gond nincs ezzel, nem is írtam volna semmit. zila válaszát 100%-ban osztom.
18

-.-

deadcode · 2008. Nov. 7. (P), 12.27
Nem véletlenül írtam, amit írtam, az első hozzászólásoddal semmivel sem járultál a dologhoz, csak leszóltál, ráadásul úgy, hogy nagyrészt irreleváns volt, amit felvetettél. Akár erőforrás-pazarlás, akár nem, ebben az esetben szükség van a rekurzióra, mert a másik út a tábla átalakítása lenne. Kérdés, hogy érdemes-e párszáz vagy akár párezer sornyi adatnál ezt megtenni, illetve emberünknek egész pontosan mire is van szüksége? Erre próbáltam rávilágítani.

Amúgy még mindig nem kaptam választ arra, hogy ebben a formában tárolt adatokat hogy lehet listázni a kért módon rekurzió nélkül, pedig tényleg érdekel.
19

Engem is

Ustak · 2008. Nov. 7. (P), 15.31
Én is utánanéztem anno mikor ilyet kellett csinálnom, és az összes megoldás ebben az esetben rekurzív függvényt használt. Valami olyasmi viszont rémlik algoritmusokból, hogy minden rekurzív függvény átírható valamilyen iteratív (ez volt a jó szó?) megoldássá, de már nem emlékszem pontosan...
20

válaszok

gex · 2008. Nov. 7. (P), 17.18
na megpróbálom összeszedni.

  1. Nem véletlenül írtam, amit írtam, az első hozzászólásoddal semmivel sem járultál a dologhoz, csak leszóltál, ráadásul úgy, hogy nagyrészt irreleváns volt, amit felvetettél.

    ha neked a webfejlesztésnél az erőforrások pazarlása irreleváns, akkor lehet hogy a játékiparban kéne elhelyezkedned.
  2. Akár erőforrás-pazarlás, akár nem, ebben az esetben szükség van a rekurzióra, mert a másik út a tábla átalakítása lenne.

    szükség... hát attól függ honnan nézzük. ahonnan te nézed onnan egy rossz megoldást szükséges használni, ahonnan én nézem, onnan a táblát szükséges módosítani. véleményem szerint a cél alapján kell eszközt választani, ha te az eszközeidnek megfelelően kreálod a célokat, akkor erről felesleges a vitát folytatni.
  3. Kérdés, hogy érdemes-e párszáz vagy akár párezer sornyi adatnál ezt megtenni

    kérdés, hogy fejlesztőként hihetek-e abban hogy annyi adat lesz holnap is az adatbázisban mint ma, és holnap is feltétlenül kiválóan fog működni a ma készített kódom.
  4. illetve emberünknek egész pontosan mire is van szüksége?

    na ez az amit senki nem kérdezett meg tőle, és én a legvalószínűbbnek azt tartom, hogy fő és alkategóriákra van csak szüksége (#5), ez esetben a helyében egy fő- és egy alkategória táblában tárolnám az adataim, mert nincs szükség se rekurzióra se nested set-es megoldásra.
  5. Amúgy még mindig nem kaptam választ arra, hogy ebben a formában tárolt adatokat hogy lehet listázni a kért módon rekurzió nélkül, pedig tényleg érdekel.

    az ebben a formában tárolt adatokat sehogy, ezért ajánlottam a weblabor cikket, aminek az első részében bemutatják a rekurzióra épülő megoldást, majd a második részben mutatnak egy megoldást ami jobb. és itt lehet hogy rosszul fejeztem ki magam, de mentségemre szóljon, hogy kicsit szétzilálódtak a szálak.
9

Hatékonyság

black_lagoon · 2008. Nov. 5. (Sze), 18.28
Nem lesz gond vele, 300-400 rekord van , ebbe nem hiszem hogy belehal bármelyik szerver, meg amúgyis tanulócélú dolog, szal saját részre van csinálva, nem üzleti alkalmazás. thx +1x