Chapitre 5. Un Tutorial Hello World pas si simple

Table des matières

5.1. Introduction
5.2. Etape 1: Créer un nouveau Domaine Local
5.3. Etape 2: Créer l'arborescence des répertoires d'un projet
5.4. Etape 3: Implémenter le Bootstrapping de l'application
5.5. Etape 4: Un point d'entrée unique, le fichier Index
5.6. Etape 5: Ajouter un Contrôleur et une Vue par défaut
5.7. Conclusion

5.1. Introduction

Proposer un exemple le plus simple qui soit est devenu une tradition pour les livres de programmation, quelque soit le langage, le framework, ou la bibliothèque concerné. En général, cela signifie en faire juste assez pour afficher "Hello World" à l'écran, afin que vous puissiez voir comment les fonctionnalités de base doivent être utilisées. Ce n'est pas vraiment l'exemple le plus réaliste qui soit lorsqu'on l'applique à des Frameworks, mais c'est un point de départ qui en vaut un autre !

5.2. Etape 1: Créer un nouveau Domaine Local

Avant que nous ne nous lancions dans le code source, il est généralement recommandé de développer en utilisant un environnement un brin plus proche de ce qui sera, typiquement, notre environnement de production. Tout au long de ce livre, je développerai des applications au sein du document root d'un serveur web, plutôt que dans un sous-répertoire. Bien que vous puissiez utiliser un sous-répertoire, cela peut vous demander un peu plus de travail lorsqu'il s'agira de configurer des références d'URI à travers l'application - quelque chose que je couvrirai un peu plus en détails plus loin.

Pour l'instant, jetons un oeil à l'Annexe A : Créer un domaine local, en utilisant des Virtual Hosts Apache, qui détaille un processus simple pour la mise en place d'un domaine local, avec son propre document root distinct pour cet exemple. En utilisant ce domaine et un Virtual Host Apache, nous pouvons servir cet exemple depuis le domaine http://helloworld.tld sur notre machine de développement.

5.3. Etape 2: Créer l'arborescence des répertoires d'un projet

L'arborescence des répertoires de notre projet d'exemple est le point à traiter ensuite. Pour commencer, créons un nouveau répertoire correspondant au chemin (en excluant le sous-répertoire /public final) que vous avez utilisé plus haut comme Document Root pour notre Virtual Host helloworld. C'est là que les fichiers de notre projet seront enregistrés. Sous Ubuntu, je pourrais créer ce répertoire dans /home/padraic/www/helloworld, et, sous Windows, je pourrais utiliser C:\projects\helloworld.

Il y a toujours pas mal de discussions sur la structure à adopter pour l'arborescence des répertoires, mais le plus gros à ce niveau est en train d'être formalisé par l'effort entrepris par Ralph Schindler autour de Zend_Tool, qui permettra d'obtenir un outil en ligne de commande complet pour la génération et la manipulation de projets. Jusqu'à ce qu'il soit réellement stable et documenté, nous ne l'utiliserons pas ici, ce qui signifie que nous allons devoir effectuer un peu de travail manuel, pour ce qui est de la création de l'arborescence de répertoires.

Arborescence des répertoires de l'application

Voici l'arborescence de répertoires que je suggère. Suivre celle-ci n'est aucunement obligatoire, et vous pouvez tout à fait utiliser quelque chose de différent, en fonction de vos préférences et d'autres applications. Pour les besoins de notre exemple, nous n'avons besoin que d'un sous-ensemble de ces répertoires.

Comme vous pouvez le voir, l'ensemble du code source des Contrôleurs et des Vues sera stocké dans le répertoire /application. Les Contrôleurs et les Vues ont des conventions de chargement spécifiques au niveau du Framework ; suivre cette convention est donc logique. Nous plaçons aussi là les Modules, qui sont, pour faire simple, des regroupements distincts de Contrôleurs et de Vues (et, éventuellement, de Modèles et d'aides spécifiques à notre application et non ré-utilisables). Vous pourriez vous attendre à trouver un répertoire /application/models, à partir de ce que vous auriez pu voir dans la documentation. Je n'utilise pas ce répertoire pour l'instant, puisque les implémentations de Modèles sont incroyablement diverses : il n'existe pas une manière unique de les charger. De plus, je maintiens les Modèles comme composants de ma bibliothèque générique d'application, /library, avec les autres classes spécifiques à cette application. Cela dit, il est toujours possible de placer les Modèles dans /application/models. Vous pourriez préférer placer les Modèles dans un répertoire nommé de manière un peu plus spécifique, mais souvenez-vous que chaque répertoire contenant du code source devra éventuellement devenir une nouvelle entrée dans l'include_path de PHP. Plus loin au cours de ce livre, nous travaillerons avec des Modèles qui pourront être stockés comme traditionnellement décrit dans le Guide de Référence, puisque l'introduction de Zend_Loader_Autoload nous permettra d'être plus flexibles à ce niveau.

Tout le reste existe au niveau du répertoire parent, et tout le futur code source de l'application, en dehors des Contrôleurs, des Vues, et des classes non ré-utilisables, va être placé soit dans le répertoire /library, soit dans le répertoire /vendor. Le répertoire library est celui où je stockerai les classes généralistes utilisées au sein de cette application. Le répertoire vendor sera généralement utilisé pour des classes non-spécifiques, ou des bibliothèques tierces que je souhaiterai utiliser. La différenciation entre les deux est totalement arbitraire : j'aime juste garder mes classes et les bibliothèques tierces distinctes. Je conserve aussi le Zend Framework lui-même là, sauf s'il est déjà installé sur le serveur à un emplacement plus central et accessible depuis l'include_path.

Les répertoires restant ne constituent pas un mystère. Le répertoire config contient les fichiers de configuration. En suivant les standards qui sont en train d'émerger, ceci pourrait aussi être placé dans /application/configs. Le répertoire data permet de stocker des données sous forme de fichiers. Il pourrait s'agir de fichiers de cache, ou d'autres informations. Le répertoire public est celui où tous les fichiers accessibles par le visiteur de notre site web résideront. Le répertoire scripts, quant à lui, contient les scripts d'utilité générale, comme les tâches à lancer en utilisant cron.

5.4. Etape 3: Implémenter le Bootstrapping de l'application

Le Bootstrapping est l'étape à laquelle nous mettons en place l'environnement initial, et configurons et initialisons le Zend Framework de notre application. Ce n'est pas un fichier compliqué à écrire, mais il peut devenir de plus en plus gros au fur et à mesure que votre application devient plus complète. Pour que cela reste gérable, je vous suggère fortement de l'implémenter sous forme d'une classe contenant de petites méthodes unitaires. Découper le Bootstrap fera des merveilles pour votre santé mentale. Plus loin dans ce livre, nous étudierons la solution proposée par Zend Framework pour répondre à ce problème, Zend_Application, qui a été introduite par Zend Framework 1.8.

Puisque le bootsrap est une classe, l'emplacement logique où le stocker est dans /library. Bien entendu, pour pourriez le placer dans /application, mais c'est encore un autre chemin d'inclusion (à moins que vous n'utilisiez Zend_Application qui travaille avec des chemins absolus vers les classes) et si nous continuons à enregistrer des classes un peu partout, nous allons finir avec l'include_path de l'enfer ! Pour l'instant, en considérant que vous n'utilisez pas Zend_Loader_Autoloader, gérer les Modèles dans /library avec notre classe de bootstrap enlève deux entrées à l'include_path. Nous allons enregistrer le nouveau bootstrap comme fichier spécifique à notre application, sous l'espace de noms ZFExt, ce qui signifiera qu'il sera enregistré dans /library/ZFExt/Bootstrap.php.

Bien... Vous devez maintenant comprendre pourquoi ce chapitre est appelé tutorial pas si simple !

A priori, vous êtes ici pour apprendre, cela dit, donc le bootstrap présenté au-dessus est bien plus complexe que l'exemple minimaliste que vous trouverez dans le Guide de Référence. Ce que j'ai fait ici passe par deux étapes. Premièrement, j'ai structuré le bootstrap comme une classe avec des méthodes distinctes pour les différentes étapes et tâches du bootstrapping. Et, secondement, j'ai mis en place des valeurs par défaut pour toutes les sorties efffectuées par l'application, en modification les configurations de Zend_View (qui génére la sortie de l'application en utilisant des templates) et de Zend_Controller_Response_Http (qui gère les en-têtes et les mécanismes de l'envoi effectif des réponses au client).

Les premières étapes sont plutôt simples. Notre gestion d'environnement, qui, dans le futur, devrait être rendue configurable, prépare PHP pour notre application, avec quelques valeurs de configuration, niveau de rapport d'erreurs, information de timezone (non nécessaire si définie dans php.ini), et une fonction d'autoload, pour que nous n'ayons pas besoin d'utiliser require_once dans notre code source. Notre autoloader personnalisé contraste avec le plus utilisé Zend_Loader, mais il est bien plus léger que l'implémentation de Zend_Loader, qui effectue toute une série de tâches généralement inutiles (à ce sujet, vous pouvez consulter l'Annexe B). La configuration actuelle d'environnement est pensée pour le développement, ce qui explique que les erreurs seront affichées.

L'étape suivante, au sein de la méthode prepare(), est de configurer le Front Controller. Comme discuté précédemment, avec une architecture Modèle-Vue-Contrôleur, l'application n'a généralement qu'un seul point d'entrée, par lequel toutes les requêtes doivent passer. Pour Zend Framework, c'est le Front Controller défini par la classe Zend_Controller_Front. La classe Front Controller utilisée par Zend Framework est un singleton (c'est d'ailleurs sa "fonctionnalité" la plus ennuyeuse - les singletons devraient être évités lorsqu'ils ne sont pas nécessaires). Dans la méthode setupFrontController(), nous paramétrons quelques flags pour être sûr qu'un objet Response soit retourné, plutôt que de simplement être affiché, hors de notre contrôle. Nous faisons aussi en sorte que les Exceptions soient levées de manière visible, plutôt que de rechercher un ErrorController qui n'existe pas encore au sein de notre application. Finalement, nous indiquons au Front Controller où il peut trouver les Contrôleur et Vues de notre application.

L'étape finale, où nous créons une instance distincte de l'objet de Réponse, Zend_Controller_Http_Response, existe pour que nous puissions spécifier une en-tête Content-Type par défaut pour les réponses de l'application. Cela permet de s'assurer que, sauf si spécifié autrement, toutes nos sorties seront automatiquement envoyées aux clients accompagnées d'une en-tête Content-Type valant text/html, avec un encodage en UTF-8. C'est une bonne pratique, pour éviter toute confusion dans le cas où nous ne définirions pas ceci explicitement dans l'application. Si cette valeur n'est pas initialisée, la valeur par défaut de Content-Type définie dans php.ini peut être utilisée à la place.

Une fois que l'environnement et le Front Controller sont configurés, l'étape finale est de mettre en place des valeurs par défaut du même type pour nos Vues. Actuellement, Zend_View, contrairement aux autres composants, utilise par défaut l'encodage ISO-8859-1 (il en va de même pour les aides de Vues), qui ne fera tout simplement pas l'affaire si vous souhaitez utiliser en sortie des caractères tenant sur plusieurs octets (comme celui dans mon nom !). C'est un point quelque peu génant, et un bug reporté il y a bien longtemps, mais conservé pour éviter tout problème de rétro-compatibilité avec des versions plus anciennes de Zend Framework. Pour changer l'encodage par défaut, nous allons devoir obtenir une nouvelle instance de la classe Zend_View, déclarer que nous voulons utiliser un encodage plus approprié, comme l'UTF-8, et implanter cet objet Vue altéré au sein de l'aide d'Action ViewRenderer. Cet aide est utilisé automatiquement par tous les Contrôleurs pour gérer les Vues, ce qui signifie qu'en définissant explicitement un objet Vue à utiliser, nous éviterons qu'un objet Vue non modifié soit automatiquement instancié à la place. En supposant que nous générerons du HTML par défaut, il est aussi fortement recommandé de définir un DOCTYPE HTML par défaut, puisque cette option de configuration a un impact sur d'autres composants (Zend_Form, par exemple) au moment où ils sont rendus. Encore une fois, c'est génant si vous oubliez ceci, puisque vous pouvez vous retrouver avec des formulaires générés en utilisant un doctype différent du reste de la page, par exemple. Bien entendu, nous préférerions que tout ce qui est rendu en HTML le soit en suivant le DOCTYPE préféré par les Vues de l'application.

Comme vous pouvez le voir, écrire un Bootstrap est un peu comme partir en guerre. Il ne survit jamais au premier contact, et vous serez en permanence en train d'ajouter des chemins, des options de configuration, et en train d'apporter d'autres modifications au fur et à mesure que le temps passera. Le code reproduit plus haut présente une base de départ possible, mais, au prochain chapître, nous ferons connaissance de Zend_Application, qui permet une approche plus standard.

5.5. Etape 4: Un point d'entrée unique, le fichier Index

Nous avons un Bootstrap en place, mais il n'est utile que si nous l'exécutons quelque part. Comme nous l'avons vu précédemment, toutes les applications basées sur une architecture Modèle-Vue-Contrôleur (MVC) ont un point d'entrée unique. Dans le cas de PHP, c'est quasiment toujours un fichier nommé index.php, le fichier d'Index.

Puisque l'index est chargé automatiquement par quasiment n'importe quel serveur web supportant PHP, si aucun autre chemin de fichier n'est donné, c'est l'emplacement où nous application sera chargée en premier lieu. C'est aussi l'endroit où nous pouvons effectuer toute modification manuelle de l'include_path de PHP qui serait nécessaire par rapport à l'environnement de notre serveur local (autres que les chemins que notre boostrap peut automatiquement charger, de par sa conception). Cela dit, je préfére ne pas casser la convention PEAR sans bonne raison, donc, la seule chose que nous devrions effectuer dans index.php est de lancer le Bootstrap !

Créons le fichier index.php dans le répertoire /public de notre projet, contenant :

Si vous utilisiez des bibliothèques avec des chemins d'inclusion non conventionnels, il vous faudrait ajouter ces répertoires d'inclusion ici, ou les configurer au sein de la classe de bootstrap. Pour le moment, cela dit, tout ce que nous utilisons peut être chargé automatiquement par le bootstrap.

[Note]Note

La convention PEAR est plutôt simple. Elle défini une règle déclarant que le nom d'une classe doit refléter son chemin relatif. Par exemple, Zend_Controller_Front devrait être une classe contenue dans un fichier dont le chemin correspond au chemin relatif Zend/Controller/Front.php quelque part au sein de votre include_path.

Nous avons un petit problème avec notre théoriquement unique point d'entrée : il va à l'encontre de la manière dont HTTP fonctionne en pratique. Comment pouvons-nous communiquer les informations indiquant quelle partie de l'application nous essayons d'atteindre, si le seul fichier disponible est index.php ? Nous avons besoin de pouvoir utiliser une URL qui, par défaut, suit la forme http://domain.tld/controllername/actionname pour que le Routeur de l'application puisse appeler la bonne méthode d'action de la bonne classe Contrôleur. Quelque soit le serveur web, c'est voué à l'échec, puisqu'il croira que nous essayons de joindre un chemin de fichier correspondant au chemin de l'URL - c'est-à-dire, le répertoire controllername/actionname/. Pour contourner ce problème, il faut que nous puissions passer le chemin depuis l'URL à index.php, tout en faisant en sorte que le serveur web comprenne que nous effectuons effectivement toutes nos requêtes via index.php.

Heureusement, les serveurs web fournissent une fonctionnalité nommée ré-écriture d'URL, qui nous permet de transformer toutes les URLs (correspondant à certains critères) en une nouvelle URL qui pointe sur index.php, pour créer une URL finale qui ressemble plus à quelque chose du genre de http://domain.tld/index.php/controllername/actionname. Bien entendu, ce critère doit exclure toutes les URLs de ressources que nous ne souhaitons pas voir passées à l'application comme un simple paramètre, comme nos feuilles de styles, nos javascripts et nos images. Celles-là doivent toujours être servies directement.

En supposant que vous utilisiez Apache comme server web, il se peut que vous ayez à activer la ré-écriture d'URL en activant le module rewrite. Ce module est désactivé par défaut sur un grand nombre d'instances d'Apache fraichement installées. Cela passe par la modification du fichier de configuration d'Apache, ou, sous Ubuntu, par l'utilisation de la commande a2enmod (qui est plutôt pratique).

Si vous utilisez Ubuntu, essayez ceci :

sudo a2enmod rewrite

Cette commande joue avec un lien symbolique et ajoute le fichier de configuration de rewrite de manière à ce qu'il soit automatiquement chargé comme faisant parti de la configuration globale d'Apache. Vous devrez recharger Apache pour que toute modification au niveau des modules prenne effet, ce qui se fait, sous Ubuntu, en utilisant :

sudo /etc/init.d/apache2 reload

S'il vous faut modifier manuellement le fichier de configuration, vous ne devriez normalement avoir qu'à ajouter quelque chose du style de la ligne suivante (ici encore, rechargez Apache ensuite) :

LoadModule rewrite_module modules/mod_rewrite.so

Pour ceux d'entre vous qui n'utilisent pas Apache, veuillez consulter la section sur Zend_Controller du Guide de Référence pour obtenir des informations spécifiques à votre environnement.

Pour pouvoir utiliser les ré-écritures d'URL, ajoutez le fichier suivant, nommé .htaccess, au répertoire /public :

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d

RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]

Si vous comptez héberger votre application dans un sous-répertoire, il vous faudra aussi ajouter une directive RewriteBase, pour être sûr que les règles excluent cette portion des URLs, et ne prennent en compte que les éléments de chemins après ce point au moment où les ré-écritures vers index.php se feront.

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d

RewriteBase /subdirectory/
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]

Le fichier .htaccess défini plusieurs règles de ré-écriture, qui assurent que toutes les requêtes soient renvoyées vers le fichier index de notre application lorsque c'est approprié. Il est conçu de manière à faire correspondre toutes les URLs, sauf celles spécifiées par les conditions de ré-écriture qui précédent - ici, si l'URL fait référence à un fichier qui existe (avec une taille supérieure à zéro), à un répertoire, ou à un lien symbolique. Cela permet de s'assurer que vos javascript, css, et tout autre fichier non-PHP, pourront être servis directement, même s'ils sont centralisés ailleurs, et référencés seulement via des liens symboliques.

[Note]Note

Si vous voulez gagner un brin de vitesse, une bonne idée est souvent d'entrer le contenu de ce fichier .htaccess directement dans la configuration Apache pour le Directory courant (nous l'avons configuré plus haut, lorsque nous avons ajouté un nouveau Virtual Host). Vous pouvez ensuite effacer le fichier .htaccess, et Apache n'aura pas à l'analyser à chaque requête, puisqu'il sera chargé de manière permanente au démarrage d'Apache. Cela dit, il vous faudra redémarrer Apache chaque fois que vous voudrez apporter des modifications aux règles de ré-écriture.

5.6. Etape 5: Ajouter un Contrôleur et une Vue par défaut

Lorsque nous discutions du Modèle-Vue-Contrôleur (MVC), nous avons noté que le Contrôleur était la partie responsable du câblage de l'application, permettant aux saisies utilisateur d'être mises en correspondance avec le Modèle, et les Modèles liés aux Vues lorsque c'est nécessaire. Le Contrôleur est donc l'un des premiers composants avec lesquels vous allez travailler, pour toutes les fonctionnalités que vous allez ajouter à une application.

Avec Zend Framework, tous les Contrôleurs sont nécessairement des sous-classes de Zend_Controller_Action. Cette classe de base force quelques conventions par défaut, que vous devriez garder à l'esprit. Par exemple, il a été décidé que la comportement par défaut de tous les Contrôleurs serait de générer automatiquement un rendu via des Vues. Cela signifie que vous n'avez pas besoin de vous soucier de spécifier manuellement quels templates de Vues doivent être rendus. A la place, une aide d'action (Action Helper) nommée View Renderer (Zend_Controller_Action_Helper_ViewRenderer) est automatiquement appelée. Dans notre classe de bootstrap définie précédemment, nous avons ajusté le comportement par défaut, en s'assurant que le View Renderer utilise une instance de Zend_View ayant un encodage par défaut en UTF-8 (plutôt que ISO-8859-1). Il existe des solutions pour désactiver le rendering automatique des Vues, comment documenté dans le Guide de Référence, ce qui est souvent utile lorsque vous avez besoin de contourner Zend_View (par exemple, pour envoyer en sortie des documents JSON ou du XML, qui ne sont pas basés sur un template, et n'ont pas besoin de traitement supplémentaire).

Déterminer quel Contrôleur doit être utilisé est le travail du Routeur (Zend_Controller_Router_Route et les classes qui lui sont proches), qui utilise la valeur de l'URL qui contient le nom de la classe du Contrôleur et de la méthode à utiliser, ou qui fait la correspondance avec une Route configurée de manière à fournir les noms des Contrôleur et Action à utiliser par défaut. En l'absence de telles informations, le Routeur utilisera par défaut la valeur "index" pour chacun des deux. Puisque nous n'avons l'intention d'effectuer des requêtes que vers la racine de http://helloworld.tld, nous aurons besoin d'un Contrôleur Index contenant une Action Index ; c'est-à-dire un Contrôleur qui puisse répondre aux valeurs par défaut du Routeur, qui considère en fait que cette URL est identique à http://helloworld.tld/index/index. Voici le code source pour le fichier /application/controllers/IndexController.php :

La méthode init() peut être ignorée, puisqu'elle ne sert qu'à initialiser des données spécifiques à ce Contrôleur, et que nous n'en n'avons, ici, aucune. La méthode indexAction(), elle, est plus intéressante, même si elle n'a aucun contenu, ce qui est tout à fait acceptable, puisqu'elle n'a besoin de contenir du code que si nous souhaitons interagir avec un Modèle ou d'autres classes. Ici, nous n'avons rien de tout cela. En fait, ici, cette méthode agit uniquement comme une étiquette indiquant à l'aide d'action ViewRenderer qu'il faudra rendre la Vue portant le nom que la-dite méthode.

Pour expliquer la mise en correspondance, un Contrôleur Index contenant une méthode indexAction() correspond à un template de Vue enregistré dans le fichier /application/views/scripts/index/index.phtml. Cela signifie que ErrorController::indexAction() correspondrait au template /application/views/scripts/error/index.phtml, et ainsi de suite. C'est une convention toute simple. Créons maintenant un template pour l'action IndexController::indexAction() ; il sera enregistré sous /application/views/scripts/index/index.phtml :

Avec Zend Framework, les templates fonctionnent en étant inclus dans la portée de l'objet Zend_View. En conséquence, toutes les propriétés et méthodes accessibles par Zend_View sont aussi accessibles depuis les templates, en utilisant $this (pour faire référence à l'instance courante de Zend_View pour laquelle la portée des variables s'applique).

C'est un template parfaitement valide et qui fonctionne ; mais quelque chose que nous verrons plus en détail ultérieurement est le concept d'aides de Vues (View Helpers). Pour faire court, une aide de Vue encapsule des tâches de présentation fréquemment utilisées au sein d'une classe d'aide. Par exemple, allons-nous ajouter la chaîne de Doctype à des dizaines de templates ? Si nous faisons cela, et que le Doctype change, nous aurons des dizaines de templates à modifier. Donc, non, nous ne ferons pas comme ça. Zend_View a une aide que nous avons utilisé dans le bootstrap pour définir un Doctype par défaut. De la même manière, nous avons utilisé une autre aide dans le bootsrap pour ajouter une en-tête http-equiv avec un Content-Type par défaut à la section des informations meta du head de notre page. En utilisant ces deux aides, qui peuvent être affichés directement du fait qu'ils implémentent indirectement la méthode magique __string(), nous pouvons réduire notre template à :

Maintenant, nous avons toujours "en" en trois emplacement différents ; nous pourrions automatiser cela avec une aide de Vue pour être sûr qu'ils soient tous les trois mis à jour en fonction de la langue de notre contenu. Cela montre pourquoi les aides de Vues sont utiles : nous pouvons leur confier des tâches en rapport avec la modification de Vue, afin qu'elles soient réutilisables un grand nombre de fois, y compris dans différentes Vues. Il n'est pour l'instant pas nécessaire de comprendre en détail le fonctionnement des aides de Vues ; pour l'instant, tout ce que vous avez besoin de savoir est qu'elles existent !

Maintenant, éditons IndexController.php pour passer le titre de la page (référencé par $this->title dans le script de Vue) à la Vue :

Tous les Contrôleurs doivent hériter de Zend_Controller_Action, puisque cette classe contient toutes les méthodes internes et propriétés communes à tous les Contrôleurs. Si vous avez besoin de tuner le Contrôleur de base pour ajouter de nouvelles méthodes ou propriétés, vous pouvez le faire en définissant une sous-classe de Zend_Controller_Action, et, ensuite, en faisant en sorte que tous les Contrôleurs de votre application héritent de cette sous-classe à la place. Toutefois, soyez extrêmement prudent lorsque vous sous-classez de cette façon : c'est utile pour ajouter de nouvelles propriétés à la classe, mais les nouvelles méthodes sont souvent mieux ajoutées en tant qu'aides d'actions distinctes, pour éviter d'en arriver à un Contrôleur père qui soit à peu de chose près un gros paquet de code spaghetti peu cohérent et difficile à maintenir.

Notre nouvelle méthode d'action ne gère pas du tout le rendering : comme dit plus haut, celui-ci est effectué automatiquement via le View Renderer qui est activé par défaut. Tout ce que nous avons à faire est renseigner les données dont nous avons besoin dans la Vue. Vous pouvez ajouter à la Vue à peu près tout ce que vous voulez de cette manière, puisque vos données devriendront simplement des propriétés dans le template de la Vue. Donc, n'hésitez pas à ajouter des objets et des tableaux. Si vous utilisiez Smarty ou PHPTAL, les choses pourraient être un peu différentes. On en revient finalement au concept de la Vue utilisant des Modèles, dont nous avons discuté plus tôt : de manière générale, un Modèle est un objet ; il n'y a donc aucune raison de limiter les Vues à de simples arrays lorsqu'il est plus simple ou pratique de passer des objets.

Plus haut, nous avons dit à la Vue que les templates pouvaient faire référence à une propriété publique nommée "title", et lui avons affecté la valeur "Hello, World!". Une fois que la méthode d'Action est terminée, le View Renderer va entrer en action, et essayer de rendre un template localisé à /application/views/scripts/index/index.phtml.

Au sein du script de Vue, nous échappons le titre, en considérant qu'il pourrait ne pas être sûr. Il est à peu près obligatoire de tout échapper de cette manière lorsque vous générez une sortie HTML. En interne, Zend_View utilise htmlspecialchars() par défaut, et lui passe l'encodage de caractères de l'instance courante. C'est encore un de ces petits ennuis : avec Zend Framework 2.0, cet échappement sera fait automatiquement, sans que nous ayons à continuellement appeler la méthode escape().

5.7. Conclusion

Dans ce chapitre, nous avons vu un exemple relativement simple (haha !) de la manière dont Zend Framework fonctionne lorsque nous construisons une application. Nous avons aussi mis en évidence l'importance du processus de bootstrapping, puisque c'est là où la quasi-totalité de notre configuration est regroupée, y compris la mise en place de valeurs par défaut ou le travail de configuration nécessaire pour les composants de Zend Framework. Tout au long de ce livre, la gestion de plugins personnalisés, d'aides d'actions, ou d'autres classes similaires et/ou non-standard de Zend Framework se fait dans le Bootstrap, puisque c'est l'emplacement le plus logique pour s'occuper à la fois de leur configuration et de leur inclusion dans l'application.

Au chapitre suivant, nous verrons un point que nous avons omis ici, mais qui est évident pour quiconque suivant les versions récentes de Zend Framework : comment gérer la complexité de ce bootsrap en utilisant Zend_Application, avant de poursuivre en expliquant comment nous pouvons gérer les erreurs applicatives. Peu après, nous commencerons à creuser en direction d'une application réelle, puisque j'ai désespérément besoin d'un remplacement pour mon blog, et que, par chance, c'est une application simple qui nous permettra d'explorer d'autres composants de Zend Framework plus en profondeur.