Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Klasa stronicowanie
Forum PHP.pl > Inne > Oceny
Sekwer
Witam. Zabawę z klasami zacząłem niedawno i chciałbym, żeby panowie ocenili czy ta poniższa jest cokolwiek warta.

  1. <?php
  2. class pager {
  3.    protected $sep = '&nbsp;';
  4.    protected $fpage = '|&lt;';
  5.    protected $prev = '&lt;';
  6.    protected $next = '&gt;';
  7.    protected $epage = '&gt;|';
  8.  
  9.    public function __construct($id, $url){
  10.        $this -> id = $id;
  11.        $this -> url = $url;
  12.    }
  13.  
  14.    public function rpp($rpp){
  15.        if(!is_numeric($rpp)){
  16.            return false;
  17.        }
  18.        $this -> rpp = $rpp;
  19.    }
  20.  
  21.    public function rpn($rpn){
  22.        if(!is_numeric($rpn)){
  23.            return false;
  24.        }
  25.        $this -> rpn = $rpn;
  26.    }
  27.  
  28.    protected function makeurl($page, $name, $title = ''){
  29.        $url = $this -> url;
  30.        $link = str_replace('#PAGE#', $page, $url);
  31.        if($title == ''){
  32.            $string = '<a href="'.$link.'">'.$name.'</a>';
  33.        } else {
  34.            $string = '<a href="'.$link.'" title="'.$title.'">'.$name.'</a>';
  35.        }
  36.        return $string;
  37.    }
  38.  
  39.    public function nav($records){
  40.        $id = $this -> id;
  41.        $sep = $this -> sep;
  42.        $perpage = $this -> rpp;
  43.        $pernav = $this -> rpn;
  44.  
  45.        $fpage = $this -> fpage;
  46.        $prev = $this -> prev;
  47.        $next = $this -> next;
  48.        $epage = $this -> epage;
  49.  
  50.        $pages = ceil($records/$perpage);
  51.  
  52.        if($_GET[$id] == '' or !is_numeric($_GET[$id]) or $_GET[$id] < 1 or $_GET[$id] > $pages){
  53.            $page = 1;
  54.        } else {
  55.            $page = $_GET[$id];
  56.        }
  57.  
  58.        if($page <= $pernav){
  59.            $start = 1;
  60.            $lratio = $pernav - $page + 1;
  61.        } else {
  62.            if($page > $pages - $pernav){
  63.                $start = $pages - $pernav - $pernav;
  64.            } else {
  65.                $start = $page - $pernav;
  66.            }
  67.        }
  68.  
  69.        if($page > $pages - $pernav){
  70.            $end = $pages;
  71.        } else {
  72.            $end = $page + $pernav + $lratio;
  73.        }
  74.  
  75.        if($page > $pernav + 1){
  76.            $nav .= $this -> makeurl(1, $fpage, 'Pierwsza strona').$sep;
  77.        }
  78.  
  79.        if($page > 1){
  80.            $nav .= $this -> makeurl($page - 1, $prev, 'Poprzednia strona').$sep;
  81.        }
  82.  
  83.        for($l = $start; $l < $page; $l++){
  84.            $nav .= $this -> makeurl($l, $l, 'Strona: '.$l).$sep;
  85.        }
  86.  
  87.        for($r = $page; $r < $end+1; $r++){
  88.            if($r == $page){
  89.                $nav .= '<span>'.$r.'</span>'.$sep;
  90.            } else {
  91.                $nav .= $this -> makeurl($r, $r, 'Strona: '.$r).$sep;
  92.            }
  93.        }
  94.  
  95.        if($page < $pages){
  96.            $nav .= $this -> makeurl($page + 1, $next, 'Następna strona').$sep;
  97.        }
  98.  
  99.        if($page < $pages - $pernav){
  100.            $nav .= $this -> makeurl($pages, $epage, 'Ostatnia strona');
  101.        }
  102.        return $nav;
  103.    }
  104.  
  105.    public function limit(){
  106.        $get = $this -> id;
  107.        if(is_numeric($_GET[$get])){
  108.            $rpp = $this -> rpp;
  109.            $limit = $_GET[$get]*$rpp;
  110.            $this -> limit = $limit;
  111.            return $limit;
  112.        }
  113.    }
  114.  
  115.    public function start(){
  116.        $limit = $this -> limit;
  117.        if(is_numeric($limit)){
  118.            $rpp = $this -> rpp;
  119.            $start = $limit - $rpp;
  120.            return $start;
  121.        }
  122.    }
  123. }
  124.  
  125. // Wywołanie klasy
  126.  
  127. $records = mysql_fetch_array(mysql_query('SELECT COUNT(*) FROM table'));
  128.  
  129. $pager = new pager('page', './pager.php?page=#PAGE#');
  130. $pager -> rpp(25);
  131. $pager -> rpn(5);
  132. $nav = $pager -> nav($records[0]);
  133. $limit = $pager -> limit();
  134. $start = $pager -> start();
  135.  
  136. $sql = mysql_query('SELECT * FROM table LIMIT '.$start.','.($limit - $start + 1));
  137.  
  138. // ...
  139.  
  140. echo $nav;
  141. ?>
jamSoft
Co najważniejsze to nie ma linijki komentarza (ach sory jest jedna smile.gif ).
Też ostatnio budowałem taką klasę i była nieco krótsza.
Źle nazywasz nazwy funkcji. Np limit dla drugiego programisty może na pierwszy rzut oka oznaczać zakończ lub podobnie. Powinno być getLimit.
Nazwy zmiennych protected powinny zaczynać się od _

Tu znajdziesz coś nt stylu pisania w php
http://pear.php.net/manual/en/standards.sample.php

A tu gotowy pager:
pear.php.net/package/Pager

Nie wiem ile jest warta, nie zagłębiam się w jej logikę, ale browar za to, że Ci się chce smile.gif
ayeo
Witam!

~jamSoft, trochę nie masz racji. Są różne konwencje nazewnictwa. To o czym Ty mówisz to notacja węgierska. Nie jest to żaden wyznacznik, ja na przykład jej nie lubię i nie stosuję. Co do nazw metod to faktycznie powinny być jednoznaczne, ale tutaj mogą pomóc komentarze czy dokumentacja klasy.

Co do samej klasy to nie podoba mi się, że zawiera ona kod HTML - kod HTML powinien być tylko w szablonach.

Pozdrawiam!
Pilsener
Przykład źle użytego obiektowego, jaka jest tego przewaga nad zwykłym include czy choćby funkcją? Ja mam taką funkcję:
  1. <?php
  2. function tresc_pasek($l_odp,$l_odp_nastronie,$l_odp_napasku,$a) { //funkcja tworząca paginację, argumenty: liczba rekordów, rekordów na jedną stronę, liczba linków na pasku przez dwa, numer bieżącej strony
  3.   $l_odp_podz = intval($l_odp/$l_odp_nastronie)+1;
  4.   $l_odp_podz_mod = $l_odp%$l_odp_nastronie;
  5.   if($l_odp_podz_mod>0){++$l_odp_podz;}
  6.   if($a>=$l_odp_podz){$a=$l_odp_podz-1;}
  7.   if($a>1){$tablica['prev']=$a-1;}else {$tablica['prev']=0;}
  8.   if($a<=$l_odp_napasku){$koniec=$l_odp_napasku*2+2;}else{$koniec=$a+$l_odp_napasku+1;}
  9.   if($a<=$koniec-$l_odp_napasku){$star=$a-$l_odp_napasku;}
  10.   if($a>=$l_odp_podz-$l_odp_napasku){$star=$l_odp_podz-$l_odp_napasku*2-1;}
  11.   if($koniec>$l_odp_podz){$koniec=$l_odp_podz;}
  12.   if($star<1){$star=1;}
  13.   for($i=$star;$i<$koniec;++$i){
  14.      if($i<$a){$tablica[]=$i;}
  15.      if($i==$a){$tablica['active'] = $i;}
  16.      if($i>$a){$tablica[]=$i;}    
  17.   }
  18.   if($a<$l_odp_podz-1){$tablica['next']=$a+1;}else{$tablica['next']=0;}
  19.   return $tablica;
  20. }
  21. ?>
- wystarczy nakarmić argumentami a funkcja zwróci tablicę stron gotową do użycia w systemie szablonów (z zaznaczeniem oczywiście poprzedniej, następnej i bieżącej) -
użycie jest prostsze a możliwości większe, że już nie wspomnę o wydajności. Podstawową wadą Twojej klasy jest jak ja to mówię "skryptowość" - elegancka obiektówka tym się różni od skryptu, że wykonuje jakąś pracę zamiast echować fragmenty kodu html - u Ciebie co prawda nie echuje, ale niewielka różnica: zobacz, co trzeba zrobić, by tego użyć na swojej stronie - trzeba na dzień dobry dostosować kod HTML i źrodło zmiennych, który jest dodatkowo rozpiżony po całej klasie - pozwól też użytkownikowi decydować w jaki sposób ma przekazywać parametry, w jakim celu ta klasa ma ingerować w zapytanie do bazy, jak nie wiadomo co chce użytkownik wyświetlić i skąd - a jak będzie chciał porcjować pliki z folderu, tekst na strony albo dane z pliku? A jak chcę wysłać numer strony postem, ajaxem lub zapisać w sesji/pliku/ciastku? Stronicowanie to ma dzielić na strony a nie dorabiać do tego całą "otoczkę".
Sekwer
Chciałem napisać stronicowanie wyłącznie do mysql. Pilsener kod, który podałeś jest chyba ze skryptu stronicowania Dariusza Majgiera (głowy nie dam).
Speedy
Cytat(Sekwer @ 23.07.2009, 20:22:50 ) *
Chciałem napisać stronicowanie wyłącznie do mysql. Pilsener kod, który podałeś jest chyba ze skryptu stronicowania Dariusza Majgiera (głowy nie dam).


Bez sensu. Kogo obchodzi, jakie dane stronicujesz? Źródło danych nie powinno mieć w takim przypadku znaczenia. Nie ważne, czy dane pochodzą z pliku *.txt, zserializowanej tablicy, bazy mysql, pgsql, oracle, firebird, pliku *.xml, czy diabli wiedzą czego jeszcze, to klasa, czy funkcja ma działać. Jeśli tak nie jest, to pojawił się błąd projektowy. Radzę zapoznać się z oklepanym wzorcem MVC, a w szczególności z warstwą modelu.
Pilsener
Cytat(Sekwer @ 23.07.2009, 18:22:50 ) *
Pilsener kod, który podałeś jest chyba ze skryptu stronicowania Dariusza Majgiera (głowy nie dam).
- kiedyś znalazłem tą funkcję na tym forum i gruntownie przebudowałem, jest to rozwiązanie logiczne i popularne, więc na pewno ktoś ma w arsenale coś mniej lub bardziej podobnego.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.