Jump to content
ciubyever

Frame-uri HTML

Recommended Posts

Posted (edited)

Paginare perfecta in php

Paginarea este un subiect care a fost discutat si ras-discutat - pot fi gasite zeci de articole si referinte catre cu si catre clase care se ocupa de prelucrarea seturilor de rezultate.

Aceste "solutii" sunt restrictive si nu incurajeaza reutilizarea codului.Acest tutorial isi propune sa abstractizeze o clasa care sa se ocupe de managementul rezultatelor, implicit renuntarea la dependinta de conexiuni la baza de date sau cereri SQL. Metoda discutata in acest tutorial ii permite dezvoltatorului / programatorului sa isi creeze propriile sale layout-uri si sa le inregistreze pur si simplu folosind un pattern orientat pe obiecte, cunoscut sub numele de Strategy Design Pattern

Ce este Strategy Design Pattern ?

Sa consideram urmatoarele: ai in site-ul tau o sumedenie de pagini pentru care rezultatele dintr-un query sunt paginate. Site-ul tau foloseste o functie sau o clasa care se ocupa de obtinerea rezultatelor si afisarea lor in pagina.Toate bune si frumoase, pana in momentul in care te decizi sa schimbi layout-ul link-urilor de paginare, pe una sau mai multe pagini. Pentru a obtine rezultatul dorit va trebui sa modifica metoda careia i-a fost incredintata aceasta responsabilitate.

Folosind capabilitatile polimorfice ale PHP-ului, o clasa generala (asa cum este cea pe care o vom construi in acest articol) foloseste un obiect care implementeaza o interfata, si defineste implementari concrete pentru metodele definite in acea interfata.In timp ce o interfata nu poate fi instantiata, ea poate referentia clase care o implementeaza. Deci, cand cream un layout nou, putem lasa strategia sau interfata din clasa ce paginare sa referentieze layout-urile, dinamic, la rulare. Apelarile care produc link-urile paginarii vor produce deci pagina care este randata cu layout-ul referentiat in momentul respectiv.

Fisiere necesare

Dupa cum am mentionat, acest tutorial nu se ocupa de modul in care rezultatele sunt paginate ci de cum sa folosim o interfata pentru a implementa aceasta logica pastrand flexibilitatea. Ca punct de pornire, este dISPobilia o clasa ce contine functionalitaea pentru a inregistra array-uri primitive sau obiecte - clasa Paginated - si de asemenea o interfata pe care o vor layout-urile trebuie sa o implementeze (PageLayout) si o implementare pentru un layout de pagina (DoubleBarLayout). Tot codul utilizat in acest tutorial este disponibil pentru download.

Un simplu exemplu

Urmatoarele exemple utilizeaza un array de string-uri. Iata setul de date:

* Andrew

* Bernard

* Castello

* Dennis

* Ernie

* Frank

* Greg

* Henry

* Isac

* Jax

* Kester

* Leonard

* Matthew

* Nigel

* Oscar

Iata cum vom folosi clasa Paginated:

<?php

require_once "Paginated.php";

//create an array of names in alphabetic order

$names = array("Andrew", "Bernard", "Castello", "Dennis", "Ernie", Frank", Greg", "Henry", "Isac", "Jax", "Kester", "Leonard", "Matthew", "Nigel", "Oscar");

$pagedResults = new Paginated($names, 10, 1);

echo "<ul>";

while($row = $pagedResults->fetchPagedRow()) {

echo "<li>{$row}</li>";

}

echo "</ul>";

?>

Mai intai includem clasa Paginated si inregistram un array in constructor. Constructorul primeste trei argumente, ultimile doua fiind optionale:

* Primul parametru este array-ul de elemente ce vor fi afisate - acestea pot fi tipuri primitive de date sau obiecte mai complexe

* Al doilea parametru reprezinta numarul de rezultate pe care vrem sa-l afisam in pagina

* Al treilea parametru este numarul paginii curente

In exemplul de mai sus, am folosit constanta 1 pentru a specifica "pagina 1", dar cel mai probabil ca vei dori sa trimiti informatia ca parametru din cererea la baza de date (vom detalia mai tarziu).

Apeland metoda fetchPagedRow in interiorul buclei, codul nostru itereaza [rin array, tiparind primele 10 nume din lista. Restul ar trebui sa fie incluse in pagina urmatoare, dar, momentan nu exista link catre acea pagina. In timp ce clasa Paginated se va ocupa cu accesul la orice obiect inregistrat de programator, responsabilitatea publicarii rezultatelor ii revine clasei care implementeaza interfata PageLayout.

In continuare, vom adauga cod pentru a afisa numarul de pagini, iar apoi vom studia un pic mai in profuzime felxibilitatea acestei clase.

Creaza un fisier PHP nou, ce contine urmatorul cod:

<?php

require_once "Paginated.php";

require_once "DoubleBarLayout.php";

//create an array of names in alphabetic order

$names = array("Andrew", "Bernard", "Castello", "Dennis", "Ernie", "Frank", "Greg", "Henry", "Isac", "Jax", "Kester", "Leonard", "Matthew", "Nigel", "Oscar");

$page = $_GET['page'];

$pagedResults = new Paginated($names, 10, 1);

echo "<ul>";

while($row = $pagedResults->fetchPagedRow()) {

echo "<li>{$row}</li>";

}

echo "</ul>";

$pagedResults->setLayout(new DoubleBarLayout());

echo $pagedResults->fetchPagedNavigation();

?>

Cand vom rula codul de mai sus, vom vedea o lista a primelor 10 nume, alaturi de informatii aditionale pentru orientare. Scriptul nostru va afisa lista cu nume precum si link-uri pentru navigare intre paginile disponibile (2 in cazul nostru).

In codul de mai sus am folosit o clasa DoubleBarLayout care implementeaza interfata PageLayout si contine implementari ale metodei fetchPagedLinks. Aceasta metoda primeste doi parametri: obiectul Pagination si parametri pe care dorim sa ii atasam, eventual, link-ului.Marele avantaj al acestei metode este ca profita de capabilitatile polimorfismului in PHP, permitand strategiei inregistrate sa fie fie apelata. De aceea este important sa stabilim in primul rand strategia, inainte de a apela metoda. Setarea strategiei este prin intermediul unei apelari a metodei de setare setLayout, care primeste ca parametru un obiect care implementeaza interfata PageLayout.

La o trecere cu mouse-ul peste link vei observa ca parametrul page si valoarea sa, 2, sunt incluse in URL. Totusi, daca faci clik pe acest link, in stadiul actual, pentru a ajunge in pagina a doua, vei observa ca numele care ar trebui sa apara nu apar.

Sa aflam de ce se intampla acest lucru, prin revenirea asupra constructorului Paginated.

Construcotrul primeste trei parametri:

1. array-ul cu variabile primitive sau obiecte, ce urmeaza a fi procesate

2. numarul de rezultate afisate

3. numarul paginii

Pentru ca metoda fetchPagedNavigation scrie o cerere parametru, putem inlocui valoarea 1, scrisa fortat in cod, cu valoarea prezenta in $_GET['page']. In acest fel, daca userul modifica manual valoarea din URL in ceva invalid, Paginated va trece implicit la valoarea 1. Cum alegi sa validezi ce vine in GET depinde numai de tine.

Flexibilitatea in schemele layout-ului paginii

Pentru a implementa aceasta tehnica, tot ce ai nevoie este sa creezi o strategie de layout care sa implementeze interfata PageLayout. Apoi, furnizeaza o implementare pentru metoda fetchPagedLinks.

Aceasta metoda accepta doi parametri:

1. $parent, care este obiectul Paginated

2. $queryVars, care reprezinta lista de parametri ce urmeaza a fi adaugati la numarul paginii (si este optional)

Sunt doua aspecte importante care merita mentionate:

1. Niciodata nu vei apela direct fetchPagedLinks. Toate metodele din Paginated pot fi accesate prin intermediul obiectului parinte.

2. Daca vrei sa folosesti propriile tale layout-uri, trebuie sa schimbi layout-ul resultatului pagina prin apelari ale setLayout.

Cu acestea in minte, sa cream propriul nostru layout de pagina. Il intitulam TrailingLayout. Iata codul:

<?php

class TrailingLayout implements PageLayout {

public function fetchPagedLinks($parent, $queryVars) {

$currentPage = $parent->getPageNumber();

$totalPages = $parent->fetchNumberPages();

$str = "";

if($totalPages >= 1) {

for($i = 1; $i <= $totalPages; $i++) {

$str .= " <a href="?page={$i}$queryVars">Page $i</a>";

$str .= $i != $totalPages ? " | " : "";

}

}

return $str;

}

}

?>

Clasa de mai sus, TrailingLayout, implementeaza interfata PageLayout, si ofera implementare pentru fetchPagedLinks. Adu-ti aminte ca parametrul $parent este o instanta a obiectului Paginated, de aceea putem determina pagina curenta, si totalul paginilor, apeland getPageNumber si respectiv fetchNumberPages.

Ai in vedere faptul ca stringul "Page" nu face parte din $queryVars, dar este scris de iteratia care ataseaza numerele paginilor.

Sa incercam sa implementam noul layout:

<?php

require_once "Paginated.php";

//include your customized layout

require_once "TrailingLayout.php";

//create an array of names in alphabetic order. A database call could have retrieved these items

$names = array("Andrew", "Bernard", "Castello", "Dennis", "Ernie", "Frank", "Greg", "Henry", "Isac", "Jax", "Kester", "Leonard", "Matthew", "Nigel", "Oscar");

$page = $_GET['page'];

$pagedResults = new Paginated($names, 10, $page);

echo "<ul>";

while($row = $pagedResults->fetchPagedRow()) {

echo "<li>{$row}</li>";

}

echo "</ul>";

//$pagedResults->setLayout(new TrailingLayout());

echo $pagedResults->fetchPagedNavigation("&firstLetter=l");

?>

Daca rulam scriptul de mai sus ca atare, vom primi urmatorul mesaj de eroare: "Fatal error: Call to a member function fetchPagedLinks() on a non-object"

Aceasta eroare apare pentru ca nu am inregistrat strategia pe care dorim sa o folosim inainte de a apela fetchPagedNavigation. Pentru a schimba layout-ul linkurilor de paginatie, transmitem catre metoda setLayout un parametru, care poate fi orice obiect ce implementeaza interfata PageLayout. In codul din exemplul de mai sus, de-comenteaza penultima linie si actualizeaza (refresh) pagina.

Edited by ciubyever

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...