Paginacja (stronicowanie) w PHP

Zaczynając swoją przygodę z PHP nie miałem pojęcia jak wykonać paginację newsów, która załamywałaby łańcuchy liczb w momencie, w których chce. Na dzień dzisiejszy postanowiłem napisać swój nowy pager, gdyż ten, który dotychczas używałem przez ostatnie 2 lata nie odpowiadał mi pod trzema względami:

  • nagromadzenie metod, tj. setLimit(), getLimit(), zamiast pojedynczego limit(),
  • brak możliwości ustawienia załamywania się łańcucha (domyślnie były to 2 liczby):
    1, 2 ... 6, 7, 8 ...  12, 13.
  • brak możliwości definiowania limitu, ilości elementów oraz aktualnie przeglądanej strony w jednej metodzie, najchętniej w samym konstruktorze.

Ostatnio potrzebowałem zwiększyć limit liczb “z przodu” i “tyłu” oraz “w środku”:
1, 2, 3 ... 5, 6, 7, 8, 9 ...  11, 12, 13

Dla tych, którzy ciągle szukają komponentu obsługującego paginację prezentuję Vframe_Pagination.

Implementacja od strony kontrolera (metoda krótka):

$oPager = new Vframe_Pagination($iItemsCount, $iLimit, $iCurrentPage);

Metoda długa:

$oPager = new Vframe_Pagination();
$oPager->limit($iLimit);
$oPager->items($iItemsCount);
$oPager->page($iPage);

Metody limit, items oraz page zwracają liczby odpowiadające ich nazwą niezależnie od tego, czy została podana nowa wartość w argumencie, czy nie, co jest absolutnie wygodnym (dla mnie) rozwiązaniem.

Aby wyświetlić oczekiwane rekordy, wykorzystujemy pagera:

$aData = $oModel->GetList($iUser, $oPager->start(), $oPager->limit());

Lub bezpośrednio w zapytaniu do bazy dancyh:

$sSql = "SELECT news_id FROM news LIMIT " . $oPager->start() . ", " . $oPager->limit();

Od strony widoku, prezentacja pagincaji prezentuje się w bardzo prosty sposób:

<?php echo $oPager->Render(true); ?>

Metoda render przyjmuje kolejno:

  1. $mMode (mixed: bool, null, string), jeżeli true, paginacja jest zwracana w formacie HTML. Jeżeli null, numerki stron podane w formie array’a zamiast linków HTML. Jeżeli string, zostaje zwracana wartość po renderowaniu pagera, np. element startujący przedział mnożony po limicie: $oPager->Render(‘start’);. Ten sam efekt powoduje metoda $oPager->start();
  2. $iDrawCutLimit (int) ilość numerków na początku i końcu łańcucha paginacji.
  3. $iDrawCutLimitCenter (int) ilość numerków “w środku” obok aktualnie przeglądanej strony.
  4. $bNavigation (bool) linki “poprzednia” i “następna” strona znajdujące się na początku i końcu łańcucha.

Możemy sami ostylować linki generowane przez pager. Wystarczy że w widoku dodamy swój apperance:

$this->oPager->PatternPage('<a href="?[$]">[$]</a>');
$this->oPager->PatternPageCurrent('<strong>[$]</strong>');
$this->oPager->PatternPageNavigation('<a href="?[$]" rel="nofollow">[$$]</a>', array('&laquo; poprzednia', 'następna &raquo;'));
$this->oPager->PatternSeparator('<span>...</span>');

Końcowy efekt, możemy nie wyświetlać pagera, gdy jest tylko jedna strona elementów:

<?php if($this->oPager->Render('pages') > 1) {
// wyswietl pager...
} ?>