Académique Documents
Professionnel Documents
Culture Documents
Atelier Zend Framework: Utiliser Zend Paginator Dans Un Environnement MVC Simple
Atelier Zend Framework: Utiliser Zend Paginator Dans Un Environnement MVC Simple
par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
Date de publication : 03/12/2008 Dernire mise jour :
Beaucoup de questions se posent sur Zend_Paginator, avec parfois des problmes. Pourtant ce composant, apparu dans ZendFramework 1.6, est trs simple prendre en main, condition toujours de savoir comment il fonctionne en interne. Un composant principal, qui pilote un adaptateur bas sur un pattern Itrateur, rien de plus, rien de moins. Nous allons tenter de dcortiquer tout cela ensemble.
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
I - Prsentation du composant Zend_Paginator......................................................................................................... 3 II - Mise en place de l'architecture d'exemple.............................................................................................................5 II-A - Base de donnes..........................................................................................................................................5 II-B - Modle MVC................................................................................................................................................. 6 III - Utiliser le paginateur............................................................................................................................................. 8 III-A - Pagination de la liste des membres............................................................................................................ 8 III-B - Afficher la barre de pagination.................................................................................................................... 9 IV - Amliorer.............................................................................................................................................................10 IV-A - Des URLs plus propres............................................................................................................................. 10 IV-B - Gestion des contextes XML et JSON....................................................................................................... 10 V - Autres utilisations du paginateur......................................................................................................................... 12 VI - Conclusions.........................................................................................................................................................13
-2Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
Diagramme de classes simplifi de Zend_Paginator Voila, a va mieux dja pour la comprhension. Ce diagramme de classes est simplifi, il ne prsente pas toutes les mthodes, ni les attributs de classe. Zend_Paginator est la classe principale qui va piloter la pagination d'un objet adaptateur. Zend_Paginator ne fonctionne donc pas sans adaptateur, il y a agrgation comme on peut le noter. Une mthode factory() sert simplifier la cration d'un paginateur avec directement le bon adaptateur dedans, en sachant qu'il existe dj ce jour 5 adaptateurs dans la distribution de Zend Framework. Vous pouvez crer vos propres adaptateurs, condition qu'ils implmentent Zend_Paginator_Adapter_Interface, et vous pouvez les charger dans Zend_Paginator grce sa dpendance envers Zend_Loader_PluginLoader (classe permettant de charger des composants utilisateurs de manire simple et pratique). Les adaptateurs ont tous un nom trs explicite. Je rappelle que pour Iterator, il prend en paramtre une classe implmentant l'interface PHP Iterator. Null lui, sert charger dans le paginateur rien... Le but est d'avoir une instance de Zend_Paginator mais sans donnes piloter (je rappelle qu'on ne peut crer une instance de Zend_Paginator sans adaptateur). Il n'y a ensuite plus rien faire au sujet de l'adaptateur, tout va se passer sur l'instance de Zend_Paginator. Zend_Paginator va alors avoir les rles suivants :
-3Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
1 2 3
Crer une fentre de visibilit paramtrable sur les donnes de l'adaptateur Proposer une faade de pilotage des donnes, via itration entre autres Donner le moyen d'afficher, via une vue Zend_View, le contrle de la pagination
-4Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
-5Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
main.ini
cache.lifetime = 3600 db.adapter = pdo_mysql db.params.host = localhost db.params.password = anaska db.params.username = julien db.params.dbname = mle
Nous vous supposons l'aise avec le paquet Zend_Db, et ses sous paquets comme Zend_Db_Table ou Zend_Db_Select, mme si nous tcherons de rester trs simples.
-6Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
Les sections logiques sont spares par des lignes de commentaires pour plus de visibilit. Idem pour la gestion des erreurs : nous demandons explicitement une connexion la base ( $db->getConnection() ), et si problme, on fait un vulgaire exit() PHP. Concernant la partie Zend_Db, que du "classique" nous prenons soin par contre d'insrer une instance de Zend_Cache_Core afin de mettre en cache les mtadonnes issues de la base de donnes. Ceci pour des raisons de performance videntes, mme si ici ce genre de problmatique est loin de nous concerner. Vient ensuite la section MVC. Rien de particulier, si ce n'est que l'on change la manire dont les vues sont appeles avec une inflection 'controller-action.suffix' au lieu de 'controller/action.suffix' par dfaut. Question de convenance... Aussi, nous instruisons le contrleur frontal de renvoyer les exceptions qu'il rencontre. Il n'y a donc pas de contrleur ddi la gestion d'erreurs.
-7Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
Notre classe TMembres est une Zend_Db_Table trs classique, mise en include_path, nous pouvons donc l'appeler directement, nous ne dtaillerons pas son code ici. Nous crons ensuite une instance de Zend_Paginator, grce sa fabrique factory(). Celle-ci va automatiquement reconnaitre l'objet Zend_Db_Table_Select, et agir en consquence, c'est dire crer un objet Zend_Paginator encapsulant un objet Zend_Paginator_Adapter_DbTableSelect Ds lors, Zend_Paginator va piloter l'objet select sous-jacent, et nous, nous allons piloter le paginateur. Il n'y a rien faire sur l'objet select : pas besoin de chercher des rsultats, ou quoi que ce soit d'autre, au lieu de cela, il faut dire au paginateur quelles donnes il va devoir chercher. La mthode setCurrentPageNumber() dfinit la page en cours dans la fentre de pagination des donnes. La mthode setItemCountPerPage() renseigne sur le nombre de rsultats par page A partir de l, Zend_Paginator va piloter l'objet adaptateur pour lui faire chercher la bonne fentre de donnes, il n'y a plus rien faire (d'obligatoire). Eventuellement, nous dcidons de changer l'amplitude des pages que l'aide partielle de vue nous prsentera. Au lieu de montrer 10 numros de pages par dfaut, nous choisissons grce setPageRange() de n'en afficher que 2. Enfin, nous passons directement l'instance du paginateur ($page ici) la vue, et c'est fini pour la partie contrleur. Passons la vue : l'affichage des donnes membres-liste.phtml
<ul> <?php foreach ($this->listeMembres as $membre) { echo "<li>$membre->nom</li>"; } ?> </ul> -8Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
membres-liste.phtml
La vue va se servir de l'instance Zend_Paginator passe (listeMembres) et va itrer dessus. Zend_Paginator implmentant l'interface IteratorAggregate, il va en fait proxier les appels de l'itrateur sur l'objet adaptateur sousjacent. Un simple foreach fait donc l'affaire ! Et dans notre cas, nous rcuprons des objets Zend_Db_Table_Row, en ralit la boucle foreach a travers l'itrateur des Zend_Db_Table_Rowset aussi (la magie des itrateurs de PHP5 est toujours impressionnante) La ligne echo $this->listeMembres; demande d'afficher l'instance Zend_Paginator. Celle-ci possde une mthode __toString(), et elle va chercher la vue partielle que nous lui avions dfinie (setDefaultViewPartial()) afin d'afficher la barre de pagination. A quoi ressemble-t-elle ? C'est ce que nous allons voir.
En fait, on ne s'est pas embts puisque le code ci-dessus est issu de la documentation officielle, tel quel (short_open_tags PHP purs). Toutes les donnes $this-> sont mises disposition par Zend_Paginator, la documentation officielle les dtaille toutes.
-9Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
routes.ini
listemembre.type listemembre.route listemembre.reverse listemembre.defaults.controller listemembre.defaults.action listemembre.defaults.page listemembre.defaults.par listemembre.map.1 listemembre.map.2 = = = = = = = = = "Zend_Controller_Router_Route_Regex" "liste-des-membres(?:-page-(\d+))?(?:-par-(\d+))?\.html" "liste-des-membres-page-%d-par-%d.html" membres liste 1 2 page par
Voila, nous pouvons ds lors interroger nos pages avec http://somehost/paginateur/liste-des-membres-page-2par-4.html , plus cool non? Et les paramtres sont facultatifs, donc ceci fonctionne : http://somehost/paginateur/liste-des-membres-page-2.html, ou encore http://somehost/paginateur/liste-des-membres-par-4.html Des problmes restent prvoir sur les URLs inverses, car l'inverseur va crer des liens dans lesquels ces paramtres l apparaitront obligatoirement. Pour viter cela, il faut driver les classes de routage, si vous vous sentez, c'est votre exercice ;-)
<?php class MembresController extends Zend_Controller_Action { public function init() { $this->_helper->contextSwitch->addActionContext('liste', array('json','xml')) ->initContext(); } public function postDispatch() { if ($this->_helper->contextSwitch->getCurrentContext() == 'json') { $this->_helper->json->sendJson($this->view->listeMembres->getCurrentItems()->toArray()); } }
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
postDispatch() permet de court-circuiter les actions par dfaut du commutateur, car notre objet Zend_Paginator ne peut tre encod en JSON de manire directe. Il faut donc dtecter le contexte JSON, et demander le rendu JSON des entits actuellement dans le paginateur (getCurrentItems()), sous forme de tableau (c'est un Zend_Db_Table_Rowset sinon) On obtient donc quelque chose comme ceci : liste au format json
[{"nom":"Julien"},{"nom":"estelle"}]
Pour le XML, il suffit de crer une vue avec l'extension xml.phtml, et de crer le XML que l'on souhaite dedans. Par exemple comme cela : membres-liste.xml.phtml
<?php $xml = new XMLWriter(); $xml->openMemory(); $xml->startDocument(); $xml->startElement('membres'); foreach ($this->listeMembres as $membre) { $xml->writeElement('membre', $membre->nom); } $xml->endElement(); $xml->endDocument(); echo $xml->flush(); ?>
- 11 Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
<?php class IndexController extends Zend_Controller_Action { public function xmlAction() { $xml = "<data><nom>julien</nom><nom>estelle</nom></data>"; $page = Zend_Paginator::factory(new SimpleXMLIterator($xml)); $page->setCurrentPageNumber($this->_getParam('page')); $page->setItemCountPerPage(2); $this->view->items = $page; } public function arrayAction() { $phpFunctions = get_defined_functions(); $page = Zend_Paginator::factory(array_shift($phpFunctions)); $page->setCurrentPageNumber($this->_getParam('page')); $page->setItemCountPerPage(50); $this->view->items = $page; }
Nous ne montrons pas les vues, qui coulent de source. xmlAction() utilise un SimpleXMLIterator pour itrer sur tous les noeuds d'un code XML. arrayAction() nous montre une liste pagine de toutes les fonctions internes PHP. On aurait pu tout aussi bien choisir un Zend_Feed::factory('une-url') qui retourne un objet implmentant Iterator, par exemple.
- 12 Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/
Atelier Zend Framework : Utiliser Zend Paginator dans un environnement MVC simple par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
VI - Conclusions
Oui Zend_Paginator possde encore tout un tas de mthodes que nous n'avons pas vues. Elles restent simples maitriser tant qu'on a compris le principe d'agrgation et de pilotage de Zend_Paginator sur le Zend_Paginator_Adapter_* qu'il contient. Aussi, on aurait pu utiliser un objet Zend_Config avec le paginateur, on aurait pu changer le style de la barre de navigation travers les pages. Le composant est (comme d'habitude avec Zend Framework) trs souple : l'tendre pour le personnaliser n'est pas compliqu, j'ai d'ailleurs quelques ides proposer prochainement, comme le fait de pouvoir mettre en cache permanent les donnes sur lesquelles le paginateur est dj pass (la proposition est lance sur le tracker de ZF). La SPL et les itrateurs Zend_Db expliqu en dtail Les expressions rgulires en PHP Dbuter avec le modle MVC de ZendFramework
- 13 Copyright 2008 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/zend-framework/atelier/paginator/