Paginátor (stránkování výsledků) v PHP

PHP Ostatní Paginátor (stránkování výsledků) v PHP

Paginátor je script napsaný v PHP pro vygenerování odkazů pro výpis většího množství položek na jednotlivé stránky.

Tento script byl napsán pro soutěž na Devbooku a získal jako jeden ze dvou placku "Machr na PHP", za toto ocenění velmi děkuji :)

Nechť je vám script k užitku.

Třída 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é spuštění je celkem jednoduché:

Parametry:

  1. Celkový počet záznamů
  2. Počet výpisů na stránku
  3. Počáteční výpis (číslo vycházející z rozsahu celkový počet/ počet výpisů na stránku)
  4. Jméno identifikátoru DIV
  5. Jméno proměnné v URL adrese "GET"
  6. Styl začátku a konce výpisu, 0 = čísla, 1 = šipky

Povinný je jen první parametr, další budou v případě jejich nepoužití nastavené z přednastavených hodnot.

require "paginator_class.php";

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

Těším se na reakce.


Galerie

Program byl vytvořen v roce 2013.

 

Stáhnout

Staženo 301x (2.34 kB)
Aplikace je včetně zdrojových kódů v jazyce php

 

  Aktivity (1)

Program pro vás napsal David Hynek
Avatar
já jsem redaktor?

Jak se ti líbí článek?
Celkem (2 hlasů) :
333 33


 


Miniatura
Všechny články v sekci
Ostatní tutoriály v PHP
Miniatura
Následující článek
Šablonovací systém PHP_JUI - Úvod

 

 

Komentáře
Zobrazit starší komentáře (7)

Avatar
David Hynek
Redaktor
Avatar
David Hynek:

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?

Editováno 1.8.2013 21:51
Odpovědět 1.8.2013 21:51
Čím víc vím, tím víc věcí nevím.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Hynek
Kit:

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.

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

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.

 
Odpovědět 1.8.2013 22:14
Avatar
David Hynek
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
David Hynek:

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

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

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.

Odpovědět  +1 1.8.2013 22:24
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Hynek
Kit:

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.

Odpovědět  +2 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):

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.

 
Odpovědět  +1 1.8.2013 22:52
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Hynek
Kit:

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.

Editováno 1.8.2013 22:55
Odpovědět  +2 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
Odpovídá na Martin Konečný (pavelco1998)
David Hynek:

:) 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.

Odpovědět 2.8.2013 0:17
Čím víc vím, tím víc věcí nevím.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Hynek
Kit:

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.

Odpovědět 2.8.2013 1:30
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 17. Zobrazit vše