Stromová štruktúra web stránky

pmasarik | Utorok 27. 03. 2007, 20.50 | PHP

Pri tvorbe stromovej štruktúry webu každý narazí na jeden zásadný problém, ktorým je systém ukladania a vyberania dát z databáze.

Moje riešenie ktoré som vymyslel bolo otrasné, preto som prečítal kopec článkov, ktoré pojednávali o rôznych veciach o ktorých dodnes ani neviem čo znamenajú :) a na nič rozumné som neprišiel.

Začal som teda hľadať a našiel som jedno elegantné riešenie od johna, ktorý je pre mňa nedosiahnuteľným vzorom.
Ja som si to trochu upravil, ale celá logika scriptu je čisto jeho práca. Originál riešenie uverejnil na volne dostupnom fóre, kde sa riešil problém so stromovou štruktúrou.
No dosť bolo kecania, ten kto sa rozumie programovaniu si to dokáže upraviť, ale určite sa nájde kopec ľudí ktorý to nezvládnu.

Základ je databáza

Vytvoríme si jednu tabuľku, ktorá bude vyzerať nasledovne.

CREATE TABLE `texty` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `text_id` int(11) unsigned default '0',
  `obsah` text,
  `nadpis` varchar(255),
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM ;

Pre menej skúsených si to trochu ešte vysvetlíme:

  • id je stĺpec kde sa ukladá ID každého textu
  • text_id je stĺpec kam sa ukladá hodnota id nadradeného textu
  • obsah a nadpis je snáď každému jasné

Už len naplníme databázu nejakým obsahom a môžeme vyberať a nasledne vypisovať.

Pokračujeme funkciou na výber z databáze

function &getThreads() {
  $all = array();
  $sql = "SELECT id, text_id, nadpis FROM texty";
  $res = mysql_query($sql) or die(mysql_error());

  while($row = mysql_fetch_array($res)) {
      $id = $row['id'];
      $idp = $row['text_id'];
      $nadpis = $row['nadpis'];

      if(!array_key_exists($id, $all)) {
          $all[$id] = array(
              'id' => $id,
              'nadpis' => $nadpis,
              'childs' => array()
          );
      } else {
          $all[$id]['id'] = $id;
          $all[$id]['nadpis'] = $nadpis;
      }
      if(!array_key_exists($idp, $all)) {
          $all[$idp] = array();
      }
      $all[$idp]['childs'][$id] = &$all[$id];
  }
  return $all[0];
}

Táto funkcia nám vycucne z databáze a nasledne uloží do poľa $all celú stromovú štruktúru, ktorú už treba len nejako spracovať a vypísať.

Vypisovať budeme do zoznamu

function echoTree(&$tree) {
        static $level = 0;
        if(count($tree)) {
            echo '<ul>';
            foreach($tree['childs'] as $id => $node) {
                echo '<li>';
                echo $node['nadpis'];
                if(count($node['childs'])) {
                    $level++;
                    echoTree($node);
                    $level--;
                }
                echo '</li>';
            }
            echo '</ul>';
        }
    }

Ešte to treba nejako použiť, takže musíme zavolať nasledovné funkcie a stromová štruktúra je nasvete.

$tree = getThreads();
echoTree(&$tree);

Na záver ešte jedna poznámka, hlavné root menu musí mať v databáze hodnotu text_id rovnú číslu nula.


Páči sa vám tento článok, zalinkujte ho:

««« Predchádzajúci text: Číslo päť žije Následujúcí text: Zrodenie nového majstra Slovenska vo volejbale »»»

Verzia pre tlač | 9 komentárov | 2042x

Komentáre k textu

Rss komentářů tohoto textu - Formulár pre nový komentár

1
reaguj[1] web faster offtopic

nie ze by som chcel komentovat k clanku. ja len..

ten select a tlacitko na poslanie do vybrali.sme a inych ti nefunguje. posle to sice tvoju url ale domenu nedava poriadne (tusim vobec). cize sa snazi pridat url ‚69-stromova-struktura-web-stranky.html‘ a to neni celkom ono. :)

Utorok 27. 03. 2007, 22.10
2
reaguj[2] web faster len dodatok

este som chcel dodat ze sorry za offtopic, potom ten aj tento komentar pokojne zmaz :)

Utorok 27. 03. 2007, 22.15
3
reaguj[3] web tiso slovenčina

nasledovne

Aby som nebol úplne OT, tak jedno z riešení je cez jedinečný node prvkov ala číslovanie kapitol vo Worde, ale o to sa treba dosť starať…

Streda 28. 03. 2007, 01.35
4
reaguj[4] web faster

aby som sa aj ja vyjadril k rieseniu – pravdepodobne je to to najcastejsie, najbeznejsie a pre bezneho cloveka aj narozumnejsie riesenie. pri vacscich stromoch sa uz moze ukazat nevyhoda nutnosti rekurzivnej metody prechadzania stromu (ktora je sice prehladna ale nie ta najefektivnejsia). ale to fakt nie je problem bezneho cloveka.

taka perlicka: jeden katalog ma takto robenu strukturu kategoriu – je ich tam asi 1800 dokopy. algoritmu v phpcku trvalo skoro tridsat sekund kym len presiel takymto stromom (trojurovnovym, reprezentovanym ako pole poli) :)

Streda 28. 03. 2007, 08.28
5
reaguj[5] web johno

No teda ja som už úplná celebrita. Ani neviem či si to zaslúžim. Ale k veci.

[4] faster : No tak to sa mi zdá trochu prehnané tvrdenie. Pokiaľ rekurzívne nevoláš SELECTy, tak to nemôže byť až tak pomalé.

Inak odporúčam http://www.sitepoint.com/…ata-database

Streda 28. 03. 2007, 12.21
6
reaguj[6] web jules Nested trees

len pre doplnenie, da sa pouzit aj tzv. „Nested Trees“ http://www.phpriot.com/…1/page5.html

Streda 28. 03. 2007, 14.13
7
reaguj[7] web pmasarik

[1] faster : neviem prečo ti to nejde, ale mne to funguje. Inak ten select je tam zabudnutý to som len niečo skúšal :)

[3] tiso : opravené

[4] faster : ja som to pole naschvál naplnil, aby som zistil ako je to rýchle a u nich bol možno problém inde, lebo mne to valí jak guľa

[5] johno : jasne že si celebrita, aspoň pre mňa určite :-D

Streda 28. 03. 2007, 16.01
8
reaguj[8] web faster

[5] johno : [7] pmasarik : Musim povedat, ze tento algoritmus je naozaj celkom pekny (ten co vytahuje a usporiadava – bez rekurzie), ale problem vidim napriklad v tom, ako vytiahne iba urcity pocet urovni stromu z databazy (napriklad iba dve, nie vsetkych n). Da sa to nejako rozumne? Inak treba vytiahnut cely strom od nejakeho vrcholu a to moze byt niekedy zbytocne vela dat. Hm?

Štvrtok 29. 03. 2007, 21.20
9
reaguj[9] web johno

[8] faster : To bude asi najskôr tým, že ten algoritmus slúži primárne na iné účely.

Ale keďže mám dneska dobrú náladu, tak ti poviem ako sa to dá. Keď trochu zmeníš schému tabuľky a upravíš SELECT. Ostatné môžeš v kľude nechať tak ako to je. No a schému môžeš zmeniť napríklad tak, že si tam pridáš ku každej položke aj hĺbku vnorenia.

Alebo rovno použiješ modified preorder tree traversal a potom ti je celý tento algoritmus na prd.

Štvrtok 29. 03. 2007, 22.59
Pridaj komentár!

  Gravatar povolený.




Kliknutím vložíš: Vlož smajla :-) Vlož smajla :-( Vlož smajla ;-) Vlož smajla :-D Vlož smajla 8-O Vlož smajla 8-) Vlož smajla :-? Vlož smajla :-x Vlož smajla :-P Vlož smajla :-|
Komentár je formátovaný Texy! syntaxou. Nie je povolené HTML, odkazy sa prevedú automaticky. Ak sa komentár nezobrazí, neprešiel bezpečnostnou kontrolou a ja ho musím schváliť. Nevkladajte ho prosím znovu.