Layout is a topic that was discussed, debated and laughed - you can find dozens of articles and references to the classes and to deal with the processing result sets.



Some classes require parameters for paging, such as databases and resources of one or more SQL statements to be submitted to the manufacturer. Claselor care folosesc aceasta metoda le lipseste flexibilitatea - ce te faci daca ai nevoie de formatare diferita pentru numerel paginilor in antet-ul si in subsolul paginii ? Classes using this method lack flexibility - what do you do if you need different formatting for numerel page header and footer site? Te apuci si modifici functia care face output, sau sublcasa sau intreaga clasa doar pentru a modifica respectiva metoda ? Grab and modify the function which is output, or sublcasa or whole class just to modify the method?

These "solutions" are restrictive and do not encourage reuse codului.Acest tutorial aims to abstract class to handle the results management, removing the dependencies default database connections or SQL queries. 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 Method discussed in this tutorial allows the developer / programmer to create their own layouts and his record simply using an object-oriented patterns, known as the Strategy Design Pattern

What is Strategy Design Pattern?

Consider the following: you have in your site a lot of pages that results from a query are paged. 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. Your site uses a function or a class that deals with results and display them in pagina.Toate well and good, until you decide to change the layout of pagination links on one or more pages. Pentru a obtine rezultatul dorit va trebui sa modifica metoda careia ia fost incredintata aceasta responsabilitate. To achieve the desired result will be to amend the method entrusted with this responsibility.

A better solution would be to any number of layouts and want to use, dynamic one when displaying the page. Strategy Design Pattern iti permite sa faci exact acest lucru. Strategy design pattern lets you do just that. Pe scurt, Strategy Design Pattern este un design pattern orientat pe obiecte, utilizat de o clasa care vrea/poate sa-si schimbe comportamentul la rulare. In short, the Strategy Design Pattern is an object-oriented design patterns used by a class that wants / can change behavior at runtime.

Using polymorphic capabilities of PHP, a general class (such as the one we build in this article) uses an object that implements an interface, and defines concrete implementations for the methods defined in that interface interfata.In while not can be instantiated, it can class that implements reviewers. Deci, cand cream un layout nou, putem lasa strategia sau interfata din clasa ce paginare sa referentieze layout-urile, dinamic, la rulare. So we create a new layout, we leave the strategy or the paging interface to referencing class layouts, dynamically at runtime. Apelarile care produc link-urile paginarii vor produce deci pagina care este randata cu layout-ul referentiat in momentul respectiv. Call producing paginarii links will take so the page is rendered with the layout referenced in time.

Files needed

As mentioned, this tutorial does not deal with how the results are pages but how to use one interface to implement this logic preserving flexibility. 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). As a starting point is a class that contains functionalitaea dispobilia to record primitive arrays or objects - class paginated - and also an interface that layouts will have to implement (PageLayout) and a layout implementation for page (DoubleBarLayout). Tot codul utilizat in acest tutorial este disponibil pentru download. All code used in this tutorial is available for download.

A simple example

The following examples use an array of strings. Iata setul de date: Here the dataset:

* Andrew
* Bernard
* Castello
* Dennis
* Ernie
* Frank
* Greg
* Henry
* Isac
* Jax
* Kester
* Leonard
* Matthew
* Nigel
* Oscar

Of course, the code can be easily extended to use an array of integers, characters or other objects that were obtained from a database. Iata cum vom folosi clasa Paginated: Here is how we use paginated class:

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>";

First class include an array paginated and log construction. Constructorul primeste trei argumente, ultimile doua fiind optionale: The manufacturer gets three arguments, the last two being optional:

* The first parameter is the array of items to be displayed - these can be primitive data types or complex objects
* The second parameter is the number of results you want to display the page
* The third parameter is the current page number

In the example above, I used to specify constant 1 "Page 1", but most likely you will want to send information as a parameter in the database application (we will detail later). Daca este furnizat un numar invalid/inexistent de pagina, constructorul va seta 1 ca pagina implicita. If given a total invalid / non-existent page, the manufacturer will set 1 as the default page.

FetchPagedRow calling method inside the loop iterates through our code [y array, typing the first 10 names from the list. Restul ar trebui sa fie incluse in pagina urmatoare, dar, momentan nu exista link catre acea pagina. The rest should be included in next page, but currently no link to that page. 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. While paginated class will deal with access to any object registered by the programmer, the responsibility lies Publishing results PageLayout class that implements the interface.

Next, we add code to display the number of pages, then we look a little profuzime felxibilitatea in this class.

Create a new PHP file, which contains the following code:

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(); ?>

When we run the code above, we see a list of top 10 names, along with additional information for guidance. Scriptul nostru va afisa lista cu nume precum si link-uri pentru navigare intre paginile disponibile (2 in cazul nostru). Our script will display a list of names and links for navigation between pages available (2 in our case).

In the code above I used a class that implements interface DoubleBarLayout PageLayout and continue implementation of the method 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. This method receives two parameters: the object Pagination and parameters we want to attach any link ului.Marele advantage of this method is to take advantage of polymorphism in PHP capabilities, allowing strategy to be registered is called. De aceea este important sa stabilim in primul rand strategia, inainte de a apela metoda. It is therefore important to establish the first strategy, before the method call. Setarea strategiei este prin intermediul unei apelari a metodei de setare setLayout, care primeste ca parametru un obiect care implementeaza interfata PageLayout. Setting strategy is through a call setup method setLayout, which receives as parameter an object that implements the interface PageLayout.

At a crossing with the mouse over the link and you will see that the page parameter value, 2, are included in the 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. However, if you click on this link, at this stage to reach the second page, you will notice that the name should not appear to occur.

To find out why this happens, the return on the manufacturer paginated.

Construcotrul gets three parameters:

1. array of primitive variables or objects to be processed
2. number of results displayed
3. page number

For an application write fetchPagedNavigation parameter method, we can replace the value 1, forced in code written with this value in $ _GET ['page']. In acest fel, daca userul modifica manual valoarea din URL in ceva invalid, Paginated va trece implicit la valoarea 1. Thus, if the user manually change the URL value to something invalid, paginated will default to a value of 1. Cum alegi sa validezi ce vine in GET depinde numai de tine. How you choose to validate the GET comes up to you.

The flexibility of this class is done through PageLayout interface, which is part of the subject paginated. Interfata PageLayout poate referentia orice obiect care o implementeaza, si apeleaza metoda fetchPagedNavigation din Paginated, cauzand obiectul curent sa poate fi referentiat. PageLayout interface may object that implements all reviewers, and calling the method fetchPagedNavigation paginated, causing the current object can be referenced. Daca nu ai mai utilizat interfete pana acum, informatiile de aici s-ar putea sa ti se para un pic confuze, dar in principiu, rezultatul final este ca va fi apelat codul corect, iar rezultatele noastre vor fi impartite pe mai multe pagini. If you have not used interfaces before, the information here could get you to look a little confusing, but basically, the end result is the correct code will be called, and our results will be spread over several pages.

To implement this technique, all you need is to create a strategy to implement the interface layout PageLayout. Apoi, furnizeaza o implementare pentru metoda fetchPagedLinks. Then provides an implementation for method fetchPagedLinks.

This method accepts two parameters:
1. $parent, which is subject paginated
2. $queryVars, which represents the list of parameters to be added to the page number (and is optional)

There are two important issues which deserve mention:
1. You never go directly fetchPagedLinks. Toate metodele din Paginated pot fi accesate prin intermediul obiectului parinte. All methods of paginated can be accessed via the parent object.
2. If you want to use your own layouts, you must change the layout by calling the setLayout Result page.

With this in mind, to create our own page layout. Il intitulam TrailingLayout. I called TrailingLayout. Iata codul: Here's the code:

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;

Class above TrailingLayout, PageLayout interface implements, and provides implementation for 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. Remember that $ parent parameter is an instance of the object paginated, so we can determine the current page and all pages, and that calling getPageNumber fetchNumberPages.

In this simple layout, as soon as more pages appear, the script will go through the pages array and create a link and a page number for each. $queryVars este, de asemenea, scris in href ca parte a iteratiei; parametrul $queryVars este util atunci cand paginam rezultatul unei cautari care ar putea include cativa parametri. $ QueryVars is also written as part of iteration href, $ queryVars parameter is useful when a search result page could include some parameters.

Have in mind that the string "Page" is not part of $ queryVars, but iteration is written that attach page numbers.

Try to implement the new layout:

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"); ?>

If you are running the script above as such, will receive the following error message: "Fatal error: Call to a member function fetchPagedLinks () on a non-object"

This error occurs because we have not which strategy we want to use before you call fetchPagedNavigation. Pentru a schimba layout-ul linkurilor de paginatie, transmitem catre metoda setLayout un parametru, care poate fi orice obiect ce implementeaza interfata PageLayout. To change the layout of paging links, the method setLayout pass a parameter, which can be any object that implements the interface PageLayout. In codul din exemplul de mai sus, de-comenteaza penultima linie si actualizeaza (refresh) pagina. The code example above, the penultimate line, comments and updates (refresh) page.

This error occurs because we have not which strategy we want to use before you call fetchPagedNavigation. Pentru a schimba layout-ul linkurilor de paginatie, transmitem catre metoda setLayout un parametru, care poate fi orice obiect ce implementeaza interfata PageLayout. To change the layout of paging links, the method setLayout pass a parameter, which can be any object that implements the interface PageLayout. In codul din exemplul de mai sus, de-comenteaza penultima linie si actualizeaza (refresh) pagina. The code example above, the penultimate line, comments and updates (refresh) page.