PHP lapozás

Ebben a cikkben egy adatbázist fogunk lapozható formára bontani. Nagyon hasznos ez a funkció, főleg egy nagyobb MySQL adatbázisnál, amikor az embernek többszáz recordja van egy táblában és ezeket szeretné a felhasználóknak valami átlátható formában megjeleníteni. Igazság szerint az alább leírt lapokra bontás talán a legegyszerűbb megoldása ennek a funkciónak, de remélem, hasznos lesz számotokra. Az alább összefoglalt függvényt az AlbérletPlusz.hu oldalhoz készítettem, ahol jelenleg is ez a PHP szkript felelős az oldalakra bontásért. Kezdjünk is hozzá.

Először is vegyük gyorsan sorra, hogy mire van szüksége az embernek egy lapozhatóan megjelenő tartalomhoz: honnan kezdődjön a lekérdezés a MySQL táblából és meddig tartson. Igazából a legnehezebb dolog itt nem a táblából való lekérdezés, hiszen azt egy sima “SELECT * FROM tabla LIMIT x, y” paranccsal megoldhatjuk, ahol x az eltolás mértéke (tehát, hogy honnan kezdjük az adatok lekérdezését), y pedig a megjelenítendő elemek száma (hmm, milyen érdekes, pont ezekre van szükségünk egy jól működő lapozás funkcióhoz, micsoda szerencse); a bonyolult funkció a lapok számának dinamikus kiírása, mondjuk egy ilyesmi formában:

lapozas

Ezt fogjuk most megírni.

Létrehozunk egy új függvényt mondjuk lapozas néven, és paramétereknek megadjuk az eltolás mértékét és a megjelenítendő elemek számát. A paramétereknek megadunk egy alap értéket, hogy ha a meghíváskor nem kap a függvény értékeket, akkor is tudjon szépen dolgozni.

Szükségünk lesz néhány változóra is: előző oldal, aktuális oldal, következő oldal, az oldalak száma, az oldalakon megjelenítendő összes elem száma, valamint egy olyan változóra ami az aktuális oldalszámtól jobbra és balra kiszámítja, hogy hány oldalt mutassunk: egy intervallumhatárra. Ez utóbbi változót így leírva lehet kicsit nehéz megérteni, de ahogy haladunk látni fogjátok a funkcióját.

function lapozas($offset = 0, $show = 12) { //Lapozás függvény - $offset az eltolás értéke, $show a megjelenítendő elemek száma

	global $osszes; //Itt megkapjuk az összes elem számát a táblából, ezt a lekérdezéskor kell kiszámolnunk.

	$elozo = $offset - $show; //Előző oldal kiszámítása
	$kovetkezo = $offset + $show; //Következő oldal kiszámítása
	$aktoldal = (int)($offset / $show) + 1; //Aktuális oldal
	$oldalszam = $osszes / $show; //Oldalak számának kiszámítása

	if ($oldalszam > (int)($osszes / $show)) $oldalszam = (int)($osszes / $show) + 1; //Oldalszám kerekítése

A változóknak kiszámoljuk a kezdeti értékeit és ezzel meg is van az egyik lényeges adat: a kezdeti értékek. Ezekre nagy szükségünk lesz a következő lépéseknél, hiszen elég sokat fogunk számolni velük. Létrehozunk egy rendezetlen listát (<ul>), az oldalszámokat pedig ebbe fogjuk pakolgatni, majd betesszük első elemnek az “előző oldal” kiírást és linket.

	if ($oldalszam > 1) { //Ha van elég oldal, hogy megjelenítsük

		print('<ul class="scroll">'); //Rendezetlen lista létrehozása, ebben tároljuk az oldalszámokat

		if ($elozo >= 0) print('<li><a href="oldal.php?&offset=' . $elozo .'">« elõzõ oldal</a></li>'); //Előző oldal kiírása, ha nem az első oldalon vagyunk

Innentől két részre bontottam a függvényt, először is azért, mert szerintem 10 oldal alatt nem érdemes a …-os részt belerakni, mert 10-12 link még bőven kifér és átlátható; 10 felett viszont már a $range értékkel is számolgatunk majd.

Szóval 10 oldal alatt egy sima for ciklussal bedobáljuk az oldalszámokat a megfelelő linkekkel a listába. Egy kis finomság: az aktuális oldalt vastaggal fogjuk írni.

		if ($oldalszam < 10) { //Oldalszámozás, ... nélkül

			for ($i = 0; $i < $oldalszam; $i++) {
				$off = ($i * $show) + ($offset % $show); //Offset számítása
				$oldal = $i + 1; //Kiirandó oldalszám megadása

				if ($off == $offset) $oldal = "" . $oldal . ""; //Aktuális oldal vastagon írva

				print ('<li><a href="oldal.php?&offset=' . $off . '">' . $oldal . '</a></li>'); //Kiiratás
			}

		}

Ezzel meg is volnánk, most jön az érdekes rész, a …-ozás ha sok oldal van. Itt már szükségünk lesz a $range értékre, ami a már fent említett intervallumhatár értéket fogja tárolni. Ezt én 2-re állítottam, mert szerintem elég egy ötös (2 balra + aktuális oldal + 2 jobbra) intervallumot látni, de ezt nyugodtan megváltoztathatjátok. Itt be fogunk hozni 2 új változót, egy $start és egy $end változót, amik az aktuális oldaltól számolják a $range értékkel csökkentett ill. növelt értékeket. Ez azért kell, hogy ha az utolsó előtti oldalon vagyunk, ne írjunk ki utolsó+1 oldalt, a második oldalon meg -1-t. :) Lássuk akkor a kódot részletekben.

		 else { //Oldalszámozás ...-tal

			$range = 2; //Intervallum két szélének távolsága aktuális oldaltól

			if ($aktoldal >= ($range *2)) { //Ha messzebb vagyunk az első oldaltól mint $range * 2, kiírjuk az első oldal linkjét
				print ('<li><a href="oldal.php?offset=0">1</a></li>');
			}

			if ($aktoldal > ($range *2)) { //Ha már a második oldal száma nem látszik, kipontozzuk
				print('<li>...</li>');
			}

			$start = $aktoldal - $range; //$start és $end kezdeti értékek
			$end = $aktoldal + $range;

			// /!\ Kritikus rész /!\ a $start és $end pontos kiszámítása			

			if ($start < 1) { //Nem megyünk negatívaba, ha közel vagyunk az oldalak elejéhez
				$start = 1;
				$end = ($range * 2) + 1;
			} elseif ($end > $oldalszam) { //Nem megyünk túl a maximális oldalakon, ha a végén vagyunk
				$start = ($oldalszam - ($range * 2) + 1);
				$end = $oldalszam;
			}

Innentől igazából a nehezén túl is vagyunk, most egy sima for-ral ki kell iratnunk az oldalakat, majdnem úgy mint a kipontozós résznél, annyi eltéréssel, hogy most $start-tól $end-ig tesszük ezt meg.

			for ($i = $start; $i <= $end; $i++) { //Oldalak kiírása $start-tól $end-ig

				$off = ($i - 1) * $show;
				$oldal = $i;

				if ($off == $offset) $oldal = "<b>" . $oldal . "</b>";

				print ('<li><a href="oldal.php?offset=' . $off . '">' . $oldal . '</a></li>'); //Kiiratás
			}

Már majdnem készen is vagyunk, egy nagyon apró dolog van csak hátra, az utolsó ill. a következő oldal linkjének kiírása, majd a lista és a függvény lezárása.

			if ($aktoldal < ($oldalszam - ($range * 2) + 1)) {
				print('<li>...</li>');
			}
			if ($aktoldal <= ($oldalszam - ($range * 2) + 1)) {
				$utolso = $osszes - ($osszes % $show);
				print ('<li><a href="oldal.php?offset=' . $utolso . '">' . $oldalszam . '</a></li>'); //Utolsó oldal kiiratása
			}
		}

		if ($kovetkezo <= $osszes ) print('<li style="border: 0px"><a href="' . $klink . '&offset=' . $kovetkezo . '">következő oldal »</a></li>');

		print ("</ul>");
	}

}

Ezzel kész is! Nézzük meg egyben gyorsan:

function lapozas($offset = 0, $show = 12) { //Lapozás függvény - $offset az eltolás értéke, $show a megjelenítendő elemek száma

	global $osszes; //Itt megkapjuk az összes elem számát a táblából, ezt a lekérdezéskor kell kiszámolnunk.

	$elozo = $offset - $show; //Előző oldal kiszámítása
	$kovetkezo = $offset + $show; //Következő oldal kiszámítása
	$aktoldal = (int)($offset / $show) + 1; //Aktuális oldal
	$oldalszam = $osszes / $show; //Oldalak számának kiszámítása

	if ($oldalszam > (int)($osszes / $show)) $oldalszam = (int)($osszes / $show) + 1; //Oldalszám kerekítése

	if ($oldalszam > 1) { //Ha van elég oldal, hogy megjelenítsük

		print('<ul class="scroll">'); //Rendezetlen lista létrehozása, ebben tároljuk az oldalszámokat

		if ($elozo >= 0) print('<li><a href="oldal.php?&offset=' . $elozo .'">« előző oldal</a></li>'); //Előző oldal kiírása, ha nem az első oldalon vagyunk

		if ($oldalszam < 10) { //Oldalszámozás, ... nélkül

			for ($i = 0; $i < $oldalszam; $i++) {
				$off = ($i * $show) + ($offset % $show); //Offset számítása
				$oldal = $i + 1; //Kiirandó oldalszám megadása

				if ($off == $offset) $oldal = "<b>" . $oldal . "</b>"; //Aktuális oldal vastagon írva

				print ('<li><a href="oldal.php?&offset=' . $off . '">' . $oldal . '</a></li>'); //Kiiratás
			}

		} else { //Oldalszámozás ...-tal

			$range = 2; //Intervallum két szélének távolsága aktuális oldaltól

			if ($aktoldal >= ($range *2)) { //Ha messzebb vagyunk az első oldaltól mint $range * 2, kiírjuk az első oldal linkjét
				print ('<li><a href="oldal.php?offset=0">1</a></li>');
			}

			if ($aktoldal > ($range *2)) { //Ha már a második oldal száma nem látszik, kipontozzuk
				print('<li>...</li>');
			}

			$start = $aktoldal - $range; //$start és $end kezdeti értékek
			$end = $aktoldal + $range;

			// /!\ Kritikus rész /!\ a $start és $end pontos kiszámítása			

			if ($start < 1) { //Nem megyünk negatívaba, ha közel vagyunk az oldalak elejéhez
				$start = 1;
				$end = ($range * 2) + 1;
			} elseif ($end > $oldalszam) { //Nem megyünk túl a maximális oldalakon, ha a végén vagyunk
				$start = ($oldalszam - ($range * 2) + 1);
				$end = $oldalszam;
			}

			for ($i = $start; $i <= $end; $i++) { //Oldalak kiírása $start-tól $end-ig

				$off = ($i - 1) * $show;
				$oldal = $i;

				if ($off == $offset) $oldal = "<b>" . $oldal . "</b>";

				print ('<li><a href="oldal.php?offset=' . $off . '">' . $oldal . '</a></li>'); //Kiiratás
			}

			if ($aktoldal < ($oldalszam - ($range * 2) + 1)) {
				print('<li>...</li>');
			}
			if ($aktoldal <= ($oldalszam - ($range * 2) + 1)) {
				$utolso = $osszes - ($osszes % $show);
				print ('<li><a href="' . $klink . '&offset=' . $utolso . '">' . $oldalszam . '</a></li>'); //Utolsó oldal kiiratása
			}
		}

		if ($kovetkezo <= $osszes ) print('<li style="border: 0px"><a href="' . $klink . '&offset=' . $kovetkezo . '">következő oldal »</a></li>');

		print ("</ul>");
	}

}

Remélem megértettétek, hogyan is működik ez a függvény, ha nem, bátran kérdezzetek a hozzászólásoknál!

Tagek: , , , ,

17 hozzászólás van a(z) “PHP lapozás” bejegyzéshez

  1. Toti says:

    Én nem értem :D

  2. efraim says:

    Kipróbáltam volna egy új oldalamon, ami egy magyar-héber-angol szótár és jó lett volna ez a megoldás az update.php -hoz de sajnos

    Parse error: parse error in C:\wamp\www\dictionary\admin\paginate.php on line 6

    hibát ír.

    Csak annyit változtattam, hogy az eredeti 12 sort 25-re növeltem

    function lapozas($offset = 0, $show = 25) { //Lapozás függvény – $offset az eltolás értéke, $show a megjelenítendő elemek száma

    • Zoltan says:

      Így próbáld meg az elejét, szedd ki a var-okat mindenhonnan.

      $elozo = $offset – $show;
      $kovetkezo = $offset + $show; //Következő oldal kiszámítása
      $aktoldal = (int)($offset / $show) + 1; //Aktuális oldal
      $oldalszam = $osszes / $show; //Oldalak számának kiszámítása

  3. B3N says:

    Hali!

    Pontosan mysql cuccot hogy adjam meg?

    Köszi előre is!

    • Zoltan says:

      Szia

      Így mennie kéne:

      $lekerdezes = “SELECT * FROM tabla ORDER BY id DESC LIMIT ” . $offset . “, ” . $show; //$offset és $show közti eredmények kiválasztása

  4. B3N says:

    Hali!

    Próbáltam már sok féle képpen, de semmi nem jött össze mindig egy fehér oldal jön be,semmi hibával.. :S

    Pedig van a mysql be adat, és van kapcslat is.

    • Zoltan says:

      Hát akkor jöjjön a debug, próbáld kikommentelni bizonyos részeket, printtel tesztelni a változók értékeit és akkor meglesz a hiba :) A forrásnak elvileg jónak kéne lennie

  5. B3N says:

    kapcsolat*

  6. Viki says:

    Nekem hibát ír ki.

    (Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in D:\-=Weblapok\oldal.php on line 121
    Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in D:\-=Weblapok\oldal.php on line 122)

    A kódon semmit nem változtattam.
    A hiba itt van valahol:

    $lekerdez = mysql_query(“SELECT * FROM vendegkonyv ORDER BY id DESC LIMIT” . $offset . “, ” . $show); //$offset és $show közti eredmények kiválasztása
    $osszes= mysql_num_rows($lekerdez); //LEKÉRDEZÜK A SOROK SZÁMÁT
    while( $sor = mysql_fetch_assoc( $lekerdez ) )
    {
    echo $sor['username'];echo”";
    }

    • Zoltan says:

      Szerintem a hiba ott lesz, hogy a LIMIT után nincs szóköz. Próbáld meg anélkül és szólj ha nem megy :)

      • Viki says:

        Köszi a gyors választ. Kipróbáltam úgy is, és nem jött össze. Ugyan az a hiba.

        A komplett kód igy néz ki nálam:

        (int)($osszes / $show)) $oldalszam = (int)($osszes / $show) + 1; //Oldalszám kerekítése

        if ($oldalszam > 1) { //Ha van elég oldal, hogy megjelenítsük

        print(”); //Rendezetlen lista létrehozása, ebben tároljuk az oldalszámokat

        if ($elozo >= 0) print(‘« előző oldal‘); //Előző oldal kiírása, ha nem az első oldalon vagyunk

        if ($oldalszam < 10) { //Oldalszámozás, … nélkül

        for ($i = 0; $i < $oldalszam; $i++) {
        $off = ($i * $show) + ($offset % $show); //Offset számítása
        $oldal = $i + 1; //Kiirandó oldalszám megadása

        if ($off == $offset) $oldal = "” . $oldal . ““; //Aktuális oldal vastagon írva

        print (‘‘ . $oldal . ‘‘); //Kiiratás
        }

        } else { //Oldalszámozás …-tal

        $range = 2; //Intervallum két szélének távolsága aktuális oldaltól

        if ($aktoldal >= ($range *2)) { //Ha messzebb vagyunk az első oldaltól mint $range * 2, kiírjuk az első oldal linkjét
        print (‘1‘);
        }

        if ($aktoldal > ($range *2)) { //Ha már a második oldal száma nem látszik, kipontozzuk
        print(‘…’);
        }

        $start = $aktoldal – $range; //$start és $end kezdeti értékek
        $end = $aktoldal + $range;

        // /!\ Kritikus rész /!\ a $start és $end pontos kiszámítása

        if ($start $oldalszam) { //Nem megyünk túl a maximális oldalakon, ha a végén vagyunk
        $start = ($oldalszam – ($range * 2) + 1);
        $end = $oldalszam;
        }

        for ($i = $start; $i <= $end; $i++) { //Oldalak kiírása $start-tól $end-ig

        $off = ($i – 1) * $show;
        $oldal = $i;

        if ($off == $offset) $oldal = "” . $oldal . ““;

        print (‘‘ . $oldal . ‘‘); //Kiiratás
        }

        if ($aktoldal < ($oldalszam – ($range * 2) + 1)) {
        print('…’);
        }
        if ($aktoldal <= ($oldalszam – ($range * 2) + 1)) {
        $utolso = $osszes – ($osszes % $show);
        print ('‘ . $oldalszam . ‘‘); //Utolsó oldal kiiratása
        }
        }

        if ($kovetkezo <= $osszes ) print('következő oldal »‘);

        print (“”);
        }

        }
        ?>

        <?php

        $lekerdez = mysql_query("SELECT * FROM vendegkonyv ORDER BY id DESC LIMIT". $offset . ", " . $show); //$offset és $show közti eredmények kiválasztása
        $osszes= mysql_num_rows($lekerdez); //LEKÉRDEZÜK A SOROK SZÁMÁT
        while( $sor = mysql_fetch_assoc( $lekerdez ) )
        {
        echo $sor['username'];echo"”;
        }
        ?>

  7. Viki says:

    Látom most is.
    igazából a te kódod előtt csak a sql csatlakozás van.

  8. Hlaci says:

    Hi!
    Nekem egy vendégkönyvhöz kellett, ahol ugye mindíg az utolsó hozzászólások jönnek be először, úgyhogy megfordítottam a cuccot, és tökéletesen műxik! Köszönöm szépen! Üdv! Laci

  9. dlaczko says:

    Szia, leírnád kérlek pontosan hová kell rakni a mysql lekérdezést és aztán annak kiíratását, hogy működjön? Mert már lassan mindenhová tettem de mégsem működik. Köszi!

Szólj hozzá