Eredmény: 1 - 7 (7) összesen

Téma: Rekurzív menüépítés PHP-ban

  1. #1
    MinderBinder edem logója
    Csatlakozott
    09-09-02
    Hely
    Budapest
    Hozzászólás
    1.093
    Thanked 1 Time in 1 Post

    Alapbeállítás Rekurzív menüépítés PHP-ban

    Sziasztok! Írtam egy kis szösszenetet és úgy gondoltam, hogy megosztom veletek is, hátha valakinek van valamilyen építő jellegű hozzászólása


    Mint az a cikk nevéből kiderülhetett, az alábbiakban nem táplálkozási tanácsokkal kívánok szolgálni, hanem egy sokak által misztikusnak gondolt eljárásról lesz szó.

    Mi is az a rekurzió?


    A rekurzió igazából nagyjából azt jelenti, hogy egy függvény önmagát hívja meg. Ez hasonlít a ciklusokhoz, de több lehetőséget ad a programod finomhangolására. Egy egyszerű programrészlettel szemléltetném a koncepciót:

    PHP kód:
    function pluszEgy($szam) {
         if(
    $szam<10)     {
             echo ++
    $szam"<br />";
             
    pluszEgy($szam);
         }     else     { 
            echo 
    'Kész! <br />';
         }
     } 
    A fenti program egy rekurziót használva kiírja a számokat egytől 10-ig (igaz, hogy a feltétel azt vizsgálja, hogy 10-nél kisebb-e, de a programban inkrementálva írja ki a számot, tehát a következő futáskor teszteli az értéket és nem fut le újra 10-nél).

    Minek a segítségével építjük fel a menüket?


    Most, hogy a kezünkben van egy megfelelő fegyver, már csak muníció kell: a rekurzív menüépítéshez tömböket fogunk használni. A tömböknek van egy pozitív tulajdonsága, ami kifejezetten jó viszonyban van a rekurzióval: több dimenzióban is elhelyezkedhetnek és így megfelelő vizsgálattal (van-e tömb a tömbben?) meghívhatjuk újra a menü építő funkciónkat, ami így alkalmas lesz akár több szintes menürendszerek kialakítására is. Példánkban az alábbi tömböt használjuk:

    PHP kód:
    $menu_array = array(    'rolunk' => array(
            
    'display' => 'Rolunk'    ),
        
    'blog' => array( 
           
    'display' => 'Blogunk'    ),
         
    'linkek' => array( 
               
    'display' => 'Ajanlott linkek',
                
    'sub' => array(
                    
    'termekek' => array(
                        
    'display' => 'Termekeink'
                       
    'url' => 'linkek/#termekek' 
                   
    ),
                    
    'szolgaltatasok' => array(
                        
    'display' => 'Szolgaltatasaink',
                        
    'url' => 'links/#szolgaltatasok',
                        
    'sub' => array(
                            
    'helyi' => array( 
                               
    'display' => 'Helyi szolgaltatasok'
                               
    'url' => 'links/#helyi-szolgaltatasok' 
                           
    ),
                           
    'online' => array(
                                
    'display' => 'Online szolgaltatasok',
                                
    'url' => 'links/#online-szolgaltatasok' 
                          
    )
                        ) 
                   )
                )
          ),
        
    'kapcsolat' => array( 
           
    'display' => 'Kapcsolat'
        
    )); 
    Igen, ez egy többszintes menü lesz. Minden szinten van egy, vagy több elem. ’display’ jelöli a menü nevét, amit a böngészőben fog látni a felhasználó. ’url’ értelemszerűen a menüponthoz tartozó url-t, illetve ’sub’-al jelöljük azt, ha egy almenüről van szó. Ez alapján tudjuk majd a függvényben eldönteni, hogy kell-e újabb rekurzió, vagy sem.
    És hogyan működik?


    Maga a funkció nem bonyolult, de elsőre egy picit talán nehezen lesz emészthető azoknak, akik nem szoktak rekurziót használni. Úgy gondoltam, hogy egy az egyben ide teszem a függvényt és akkor nem darabokból kell összeraknod. A könnyebb érthetőség érdekében kommentekkel magyarázom el, hogy mi miért van, így remélhetőleg mindenkinek világos lesz. J

    PHP kód:
    // Az első menünk biztos nem lesz almenü, ezért  $is_sub alapértelmezettként FALSE
      
    function menutEpit($menu_array$is_sub=FALSE) {
          
    /*
           * Ha almenüről van szó, akkor adjunk neki megfelelő
           * stílust.
           */
          
    $attr = (!$is_sub) ? 'id="menu"' 'class="almenu"';
          
    /*
           * A már elkészített részeit a menünek a roppant elmés $menu változóba mentjük el
           *  a webes sztenderdekhez alkalmazkodva nem sorszámozott listában, amit itt megnyitunk:
           */
          
    $menu "<ul $attr>\n"
          
    /*
           * Először végig kell futni a tömb elemein
           */
          
    foreach($menu_array as $id => $elemek) {
              
    /*
               * Mivel minden elem egy másik tömb, ezért kell még egy ciklus, amivel végigfutunk
               * a tömbben lévő belső tömbön,
               * és az elemeit elmentjük változókba
               */
              
    foreach($elemek as $key => $val) {
                  
    /*
                   * Itt jön a varázslat, ha az elem egy másik tömböt tartalmaz,
                   * akkor egy almenüről van szó, tehát újra meghívjuk a
                   * menuEpit() függvényt, majd elmentjük egy változóba az eredményt.
                   *
                   */
                  
    if(is_array($val)) {
                      
    // fontos, hogy itt a második paraméter TRUE lesz, mert ez már egy almenü
                      
    $sub menutEpit($valTRUE);
                  }
                  
    /*
                   * ha a feltétel nem teljesül, akkor is létrehozzuk a $sub változót, de NULL értékkel
                   * ezután pedig a többi elemét a tömbnek elmentjük egy változóba (változó változó)
                   * tehát $$key = $val-ból pl $display lesz, ha a tömb $display nevű eleménél tartunk
                   */
                  
    else {
                      
    $sub NULL;
                      $
    $key $val;
                  }
              }
              
    /*
               * Ha nincs a belső tömbünkben ’url’ nevű elem (a főmenüben lesz ilyen), akkor az
               * elem ID-je lesz az url.
               */
              
    if(!isset($url)) {
                  
    $url $id;
              }
              
    /*
               * Végül kiírjuk a menü változónkba a tartalmakat. Figyeljük meg a $sub változót,
               * melynek, ha lesz értéke, akkor egy új listát fog tartalmazni (ami esetleg további
               * listákat tartalmaz stb), viszont megfelel formátumban a webes sztenderdeknek,
               * ha viszont értéke NULL, akkor nem változik semmi és nem esik szét a kódunk.
               */
              
    $menu .= "<li><a href=\"$url\">$display</a>$sub</li>\n";
              
    /*
               * A változóinkat töröljük, hogy a következő iterációban
               * biztosan üresek legyenek
               */
              
    unset($url$display$sub);
          }
          
    /*
           * Végül a $menu változó lesz a visszatérési érték
           * a felépítette menüvel
           */
          
    return $menu "</ul>\n";
      }
      
    // Ne felejtsük el, hogy kiírás nincs, tehát ezt még echo-zni kell 
      
    echo menutEpit($menu_array); 

    Összegzés


    Miért jó ez a funkció?

    Ha már eljutottál idáig, akkor valószínűleg láttad értelmét ennek az algoritmusnak, de esetleg felmerülhet benned, hogy „Oké, de miért építsek többdimenziós tömböket, ha megírhatom az egész menüt kézzel?”

    A válasz nagyon egyszerű: Ezt is csak egyszer kell megírnod, viszont sokkal könnyebb utólag módosítani, mint egy hosszú kódban turkálni, valamint megkíméled magad a végeláthatatlan elágazáshalmazoktól. Ezen kívül az is mellette szól, hogy az előző okból kifolyólag kevesebb kóddal jár és áttekinthetőbb, valamint a tömböt, amiből felépíted létre tudod hozni adatbázisban tárolt struktúra alapján is, így megkímélheted magad a tömb megírásától is.
    Hogyan bővíthető?

    Igazság szerint a fent szemléltetett függvény meglehetősen egyszerű struktúrát hoz létre, tehát ezt tetszés szerint lehet bővíteni. Jó példa erre az, ha hozzáadsz minden menüponthoz egy title attribútumot is (SEO!) a tömbödben és utána csak hozzáteszed a változódat a lista elemek kiírásánál.
    Végszó


    Remélem, hogy ezzel a kis írással egy olyan megoldást nyújtottam, amit már kerestél egy ideje és hasznos lesz, mint ahogy nekem is hasznos volt, amikor először találkoztam vele. Ha esetleg felmerülne bármilyen kérdésed, vagy hibát találnál, akkor szívesen fogadok minden nemű hozzászólást.

    edem



    Utoljára módosítva: edem által : 2010-05-06 09:15
    // Only illogics can find
    // hidden flaws in a straight logic line

  2. #2
    Új tag
    Csatlakozott
    10-04-22
    Hely
    Veszprém
    Hozzászólás
    8
    Begyűjtött 0 köszönetet
    0 hozzászólásával

    Alapbeállítás re: Rekurzív menüépítés PHP-ban

    Ez tetszik.
    Köszi.
    0123456789



  3. #3
    Szerkesztő webstars logója
    Csatlakozott
    09-08-02
    Hozzászólás
    270
    Begyűjtött 25 köszönetet
    6 hozzászólásával

    Alapbeállítás re: Rekurzív menüépítés PHP-ban

    Szép tiszta átgondolt kód jól dokumentálva. Gratulálok.



  4. #4
    Bölcs Xefande logója
    Csatlakozott
    08-09-30
    Hozzászólás
    1.625
    Begyűjtött 6 köszönetet
    6 hozzászólásával

    Alapbeállítás re: Rekurzív menüépítés PHP-ban

    Örülök, hogy van ilyen, hogy csak úgy magától valaki ír egy ilyen jól kidolgozott tutorialt a többieknek , kérés nélkül



  5. #5
    MinderBinder edem logója
    Csatlakozott
    09-09-02
    Hely
    Budapest
    Hozzászólás
    1.093
    Thanked 1 Time in 1 Post

    Alapbeállítás re: Rekurzív menüépítés PHP-ban

    Az igazsághoz hozzátartozik, hogy ezt a cikket egy online magazinnak írtam, de nem kikötés, hogy máshol nem jelenhet meg, ezért tettem be ide, mert szerintem lesznek páran, akik hasznát veszik, illetve felhasználtam hozzá némi angol nyelvű anyagot is, tehát kb fele-fele az arány.

    Ha már tutorialoknál tartunk, esetleg át lehetne az egészet tenni a tutorialok témakörbe?


    Utoljára módosítva: edem által : 2010-05-06 11:51

  6. #6
    Új tag
    Csatlakozott
    14-02-26
    Hozzászólás
    1
    Begyűjtött 0 köszönetet
    0 hozzászólásával

    Alapbeállítás re: Rekurzív menüépítés PHP-ban

    Szia ez jó lenne de van benne hiba a $display válltozót hol dekllalád illetve hol kap értéket????



  7. #7
    Törzsvendég
    Csatlakozott
    08-10-10
    Hely
    Debrecen
    Hozzászólás
    107
    Thanked 1 Time in 1 Post

    Alapbeállítás re: Rekurzív menüépítés PHP-ban

    Idézet nazinorbi eredeti hozzászólása Hozzászólás megtekintése
    Szia ez jó lenne de van benne hiba a $display válltozót hol dekllalád illetve hol kap értéket????
    Ebben a sorban kap értéket: $$key = $val;



A téma címkéi:

Könyvjelzők

Hozzászólás szabályai

  • Új témákat nem hozhatsz létre
  • Válaszokat nem küldhetsz
  • Fájlokat nem csatolhatsz
  • A hozzászólásaidat nem módosíthatod
  •