MS Office week
Pouze tento týden sleva až 80 % na e-learning týkající se MS Office
50 % bodů zdarma na online výuku díky naší Slevové akci!

Paginátor (stránkovanie výsledkov) v PHP

Paginátor je script napísaný v PHP pre vygenerovanie odkazov pre výpis väčšieho množstva položiek na jednotlivé stránky.

Tento script bol napísaný pre súťaž na ITnetwork a získal ako jeden z dvoch placku "Machr na PHP", za toto ocenenie veľmi ďakujem :)

Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

Nech je vám script na úžitok.

Trieda scriptu:

<?php

class Paginator
{
  private $celkem;
  private $pocet;
  private $pozice;
  private $adresa;
  private $trida;
  private $roztec = 4; //vzdalenost od aktualni pozice -1 :o)
  private $zacatek;
  private $konec;

  /*
    první parametr  = celkový počet záznamů
    druhý parametr  = počet záznamů pro výpis
    třeti parametr  = startovací stránka
    čtvrtý parametr = ID divu výpisu pro stylování v CSS
    patý parametr   = nazev odkazu pro GET
    šestý parametr  = styl zobrazení začátku a konce (0 = šipky, 1 = čísla)
  */

  function __construct($c = 0, $p = 10, $z = 1, $t = 'paginator',$g = 'poz',$s = 0)
  {
    $this->celkem = $c;
    $this->adresa = $_SERVER['PHP_SELF'];
    $this->znak = "?";
    $this->pocet = $p;
    $this->trida = $t;
    $this->g = $g;
    $this->rozsah = ceil($this->celkem / $this->pocet);
    $this->pozice = ((isset($_GET[$this->g]) and $_GET[$this->g]*1>0)?$_GET[$this->g]:(($z>$this->rozsah)?$this->rozsah:$z)); // zjisteni pozice z URL
    $this->zacatek = ($s == 0)?"&lt;&lt;":1;
    $this->konec = ($s == 0)?"&gt;&gt;":$this->rozsah;
  }

  function __toString()
  {
    return "<div id='".$this->trida."'>\n".$this->adresa()."</div>\n";
  }

  function odkaz($a,$n,$p)
  {
    return "\t".(($n == $p)?"<strong>$a</strong>":"<a href='{$this->adresa}{$this->znak}{$this->g}=$n'>$a</a>")."\n";
  }

  public function adresa()
  {
    if($this->celkem == 0) return "\tNejsou zde žádné výpisy.\n";
    if($this->celkem <= $this->pocet) return "\tZobrazeno všech {$this->celkem} výpisů.\n";
    else
    {
      $v = "";
      $s = "";
      $p = $this->pozice;
      if($this->rozsah > ($this->roztec * 2))
      {
        $s .= $this->odkaz($this->zacatek,1,$p);
        if(($p-1000)>0) $s.= $this->odkaz("-1000",$p-1000,$p);
        if(($p-100)>0) $s.= $this->odkaz("-100",$p-100,$p);
        if(($p-10)>0) $s.= $this->odkaz("-10",$p-10,$p);
        if($p-1>$this->roztec) $s .= "\t<span>...</span>\n";
        for($a=1;$a<(2*$this->roztec);$a++)
        {
          $n = ($a+$p-((($p-1)<$this->roztec)?$p-1:($p<($this->rozsah-$this->roztec)?$this->roztec:$p-$this->rozsah+(2*$this->roztec))));
          $s .= $this->odkaz($n,$n,$p);
        }
        if($p<($this->rozsah-$this->roztec)) $s.= "\t<span>...</span>\n";
        if(($p+10)<$this->rozsah) $s.= $this->odkaz("+10",$p+10,$p);
        if(($p+100)<$this->rozsah) $s.= $this->odkaz("+100",$p+100,$p);
        if(($p+1000)<$this->rozsah) $s.= $this->odkaz("+1000",$p+1000,$p);
        $s .= $this->odkaz($this->konec,$this->rozsah,$p);
      }
      else
        for($a=1;$a<=$this->rozsah;$a++) $s.= $this->odkaz($a,$a,$p);
      return $s;
    }
  }
}
?>

A samotné spustenie je celkom jednoduché:

parametre:

  1. Celkový počet záznamov
  2. Počet výpisov na stránku
  3. Počiatočné výpis (číslo vychádzajúce z rozsahu celkový počet / počet výpisov na stránku)
  4. Meno identifikátora DIV
  5. Meno premennej v URL adrese "GET"
  6. Štýl začiatku a konca výpisu, 0 = čísla, 1 = šípky

Povinný je len prvý parameter, ďalšie budú v prípade ich nepoužitia nastavenej z prednastavených hodnôt.

require "paginator_class.php";

$vypis = new Paginator(1000,20,1,'vypis3','poz3'); //
echo $vypis;

Teším sa na reakcie.


Galéria


 

Stiahnuť

Stiahnuté 323x (2.34 kB)
Aplikácia je vrátane zdrojových kódov v jazyku php

 

Všetky články v sekcii
Knižnice pre PHP
Program pre vás napísal David Hynek
Avatar
Ako sa ti páči článok?
Ešte nikto nehodnotil, buď prvý!
já jsem redaktor?
Aktivity (1)

 

 

Komentáre

Avatar
David Hynek
Redaktor
Avatar
David Hynek:1.8.2013 21:51

Omlouvám se za tupost, ale nechápu. Já k výstupu používám jen a pouze __toString() a že je tam výstup s HTML kódem, co tam poslat? jen čistý text? ale ja tam udělám bez HTML odkazy a pod?

Editované 1.8.2013 21:51
Odpovedať
1.8.2013 21:51
Čím víc vím, tím víc věcí nevím.
Avatar
Kit
Redaktor
Avatar
Odpovedá na David Hynek
Kit:1.8.2013 22:05

Zkus se držet toho, že HTML značky smí být právě jen v metodě __toString() a nikde jinde. HTML v metodě odkaz() už nemá co pohledávat.

Zpočátku to půjde těžko, ale brzy zjistíš, že nejlepší je nejprve si všechny odkazy naházet do privátního pole v surovém stavu a teprve zavoláním metody __toString() je převedeš do HTML stringu.

Odpovedať
1.8.2013 22:05
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Odpovedá na Kit
Martin Konečný (pavelco1998):1.8.2013 22:14

A počítá se do toho i například to, že by měl vytvořen objekt třídy DOMDocument a odkazy vytvářel přes něj?
Čili že by v metodě odkaz() neměl přímo HTML, ale vytvoření nového tagu pomocí této třídy.

Odpovedať
1.8.2013 22:14
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
David Hynek
Redaktor
Avatar
Odpovedá na Martin Konečný (pavelco1998)
David Hynek:1.8.2013 22:22

A není to už zbytečné kombinování? když teprve HTML kod vytvářím.
To co píše Kit beru. Ten můj kod je krátký, ale kdyby to bylo větší, už by případná úprava HTML byla komplikovanější. Díky

Odpovedať
1.8.2013 22:22
Čím víc vím, tím víc věcí nevím.
Avatar
Kit
Redaktor
Avatar
Odpovedá na Martin Konečný (pavelco1998)
Kit:1.8.2013 22:24

DOMDocument je datová struktura typu strom. Je na zvážení, zda nejprve nasázím odkazy do array() a pak je teprve hromadně převedu do DOMDocument nebo to nahážu do DOMDocument přímo. Při generování stromu už musíš ošetřit stringy, což patří už do prezentační části. Ovšem tato část aplikace se stejně dává do vieweru, tak by to nemělo vadit.

Osobně bych použil přímo DOMDocument, ale nechtěl jsem tím David Hynek zatěžovat. Patří to mezi pokročilé techniky, které nezvládá mnoho profesionálů a místo toho se vrhají na Smarty.

Odpovedať
1.8.2013 22:24
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!
Avatar
Kit
Redaktor
Avatar
Odpovedá na David Hynek
Kit:1.8.2013 22:28

Když používáš DOMDocument, tak ve skriptu neuvidíš ani kousek HTML. Ta třída ho generuje sama, výsledkem je vždy validní XML nebo jeho fragment. Ten tvůj kód by se tím zkrátil.

Odpovedať
1.8.2013 22:28
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Martin Konečný (pavelco1998):1.8.2013 22:52

Kite, děkuji za vysvětlení.

Davide, co se ještě týká samotného Paginatoru, tak osobně mi kód přijde poměrně nepřehledný. Myslím, že nebudu jediný, komu tam chybí mezery mezi operátory (btw, někde mezery jsou, někde ne - asi by to chtělo psát jedním stylem).

Také bych byl trošku opatrnější s použitím ternárního operátoru. Například na tomto řádku

$n = ($a+$p-((($p-1)<$this->roztec)?$p-1:($p<($this->rozsah-$this->roztec)?$this->roztec:$p-$this->rozsah+(2*$this->roztec))));

mi přijde, že to přehlednost spíše zhoršilo než zlepšilo.

Taktéž bych v každém případě nevolil jednopísmenný název proměnných (kromě těch, které slouží k inkrementaci (např. pro cyklus for)).

Pak jsem ještě zvyklý psát bloky i v případě, že následuje jen jednořádkový příkaz, také si myslím, že to přidá přehlednosti.

Odpovedať
1.8.2013 22:52
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Kit
Redaktor
Avatar
Odpovedá na David Hynek
Kit:1.8.2013 22:53

Ještě koukám na tvůj zápis

if($this->celkem == 0) return "\tNejsou zde žádné výpisy.\n";

který není zrovna ideální. Představ si, že bych při prázdném seznamu chtěl generovat jiný nápis nebo bych nechtěl generovat nic. Běžně se v seznamu něco vyskytovat bude, pokud tam nebude nic, bude to výjimka:

if($this->celkem == 0) throw new Exception("Nejsou zde žádné výpisy.");

A je to. Samozřejmě je vhodné místo Exception vyrobit nějakého potomka, aby se to nemíchalo s běhovými chybami, ale pro tento účel jsem to zjednodušil.

Výhodou výjimek je mimo jiné také to, že mohou mít jiný typ návratové hodnoty než výsledek funkce. Pokud je výsledek parametrem jiné metody, ta se už neprovede. Není tedy nutné testovat data při předávání mezi objekty. Ošetření výjimky se dá udělat klidně i jediné pro celou aplikaci.

Editované 1.8.2013 22:55
Odpovedať
1.8.2013 22:53
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hynek
Redaktor
Avatar
Odpovedá na Martin Konečný (pavelco1998)
David Hynek:2.8.2013 0:17

:) tohle je paráda. Pohled od profíků je cennější než sebelepší tutoriál.

Než sem dám nějaký další svůj script tak se zkusím zlepšit.

Díky moc chlapi.

Odpovedať
2.8.2013 0:17
Čím víc vím, tím víc věcí nevím.
Avatar
Kit
Redaktor
Avatar
Odpovedá na David Hynek
Kit:2.8.2013 1:30

Neboj se toho a dávej sem další skripty. Možná bude výhodnější použít http://www.itnetwork.cz/dev-lighter

Na hodně postupů platí obyčejný selský rozum. Seznam, tabulka (slovník), pole, strom a množina. Někdy si stačí jen říct nahlas, co chceš vytvořit. Ostatní už jen bývá okolní omáčka.

Odpovedať
2.8.2013 1:30
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!