# S'initier au Zend Framework/Version imprimable

* Si vous imprimez cette page, choisissez « Aperçu avant impression » dans votre navigateur, ou cliquez sur le lien Version imprimable dans la boîte à outils, vous verrez cette page sans ce message, ni éléments de navigation sur la gauche ou en haut.
* Cliquez sur Rafraîchir cette page pour obtenir la dernière version du wikilivre.
* Pour plus d'informations sur les version imprimables, y compris la manière d'obtenir une version PDF, vous pouvez lire l'article Versions imprimables.
Une version à jour et éditable de ce livre est disponible sur Wikilivres, une bibliothèque de livres pédagogiques, à l'URL : https://fr.wikibooks.org/wiki/S%27initier_au_Zend_Framework

# Présentation
## Zend Framework

Le cadriciel PHP Zend (alias ZF) est né en 2005 à l'initiative de la société Zend. C'est une collection de composants modulaires comme les autres bibliothèques comme PEAR, Zend Framework y ajoute les bonnes pratiques issues de l'expérience et de la théorie de l'informatique objet (design pattern) utilisés de longue date avec Java.
Des sociétés participent directement au développement comme Adobe comme pour le composant Zend_Amf qui est un connecteur entre des applications flash et le serveur en PHP.
La société Zend affiche ouvertement l'objectif de concurrencer Java et .Net dans le domaine des serveurs d'applications et des systèmes d'information. La licence BSD du framework autorise ainsi l'utilisation dans des applications propriétaires.

## Pourquoi l'utiliser

La version 5 de PHP facilite l'industrialisation des développements, ainsi des solutions ont vu le jour comme CakePHP, Symfony, Zend Framework, etc.
Un framework ou cadriciel et parfois « cadre de travail » est un ensemble de bibliothèques et d'outils pour aider le développeur mais en plus il impose une rigueur sur la façon de programmer justifiée par les bonnes pratiques et les conventions communes. Un framework est un gage de qualité car un code cohérent sera plus aisé à maintenir ou à faire évoluer.
Pour le développeur les bibliothèques fondamentales sont fournies et comme les connecteurs à la base de données, la persistance et la validation de données, la génération de formulaires, etc.
Ainsi, Zend Framework est basé sur MVC et livré avec de nombreux composants (email, services web, l'I18N, etc).

## Notes

* ↑ http://framework.zend.com

# Concepts
## Le patron de conception Modèle vue contrôleur (MVC)

Zend Framework comme tous les cadriciels majeurs des langages de scripts serveurs utilise le patron de conception Modèle-vue-contrôleur qui sépare le modèle de données, l'interface utilisateur et les traitements. Ces trois parties fondamentales se nomment : le modèle, la vue et le contrôleur.
Le modèle ne s'occupe que du traitement des données, les liens avec la base de données, lecture, insertion, mise-à-jour des tuples dans une base, vérifier que les données sont bien formatées (validation). La présentation des résultats ne se fait pas dans le modèle.
La vue correspond à la présentation des résultats, par exemple un tableau HTML, PDF pour un utilisateur ou sous forme XML pour fournir un programme distant. Les évènements et les actions de l'utilisateur (clic d'un bouton, liste de sélection, etc) sont gérés dans la vue. Cette séparation permet au graphiste de travailler sans avoir à se soucier des rouages de l'application.
Le contrôleur prend en charge le déroulement du programme. La liste des actions sera dans le contrôleur. Il synchronise les événements provenant de l'utilisateur vers la base de données.
Ce patron de conception existe traditionnellement dans les langages objet comme Java comme par exemple la bibliothèque graphique SWING et est employé généralement dans les langages web comme la plateforme Adobe/Flex ou la prochaine norme W3C de formulaires Xforms. Cette orientation a été perçue très tôt par les développeurs web notamment avec la popularité du framework Ruby on Rails. L'éditeur de PHP, Zend a pris la même orientation tout en conservant les développeurs ne souhaitant pas migrer vers MVC et permet ainsi d'utiliser ZF comme une bibliothèque classique.

## Avantages et inconvénients de l'architecture MVC.

« Given enough eyeballs, all bugs are shallow » (pour assez de globes oculaires, tous les bugs sont superficiels) - Linus Torvalds.
L'avantage premier est la modularité, les objets sont réutilisables dans une autre application. Le cloisonnement ajoute en facilité de maintenance. De plus, la modification des traitements se fait indépendamment de l'affichage (la vue). Il faut préciser que les développeurs qui sont impliqués dans l'amélioration du framework proposent des composants issus de la théorie informatique (comme les design patterns) ou le fruit de l'expérience par de bonnes pratiques de programmation.
L'inconvénient est une phase de conception plus longue et ces ajouts de couches multiplient le nombre de fichiers sur le serveur. Cela nécessite des outils spécifiques de débogage et de mécanismes d'amélioration des performances (cache). Le temps d'apprentissage est à prendre en compte pour les développeurs.

## Zend Framework : Fonctionnement

L'apprentissage du fonctionnement du framework peut être un peu ardu, car cela nécessite une connaissance de quelques concepts de programmation orientée objet. Mais la consultation de la documentation, du tracker de bugs, des blogs des développeurs permettent d'en comprendre la globalité.
Le processus d'une requête est :
* Le bootstrap (html/index.php) est le point d'entrée dans l'application, il s'agit de l'implémentation du design pattern contrôleur frontal et d'un singleton. Toutes les requêtes passent par cet objet, à sa charge d'acheminer (dispatcher) vers les actions (suivant une route par défaut ou définie par le concepteur). Les réponses sont collectées par cet objet.
* La requête peut d'abord être pré-traitée dans un plugin, cela permet au concepteur d'effectuer des traitements en tout début de requête.
* La requête est routée, c'est à dire que l'on traduit l'URI d'entrée en lien vers le bon contrôleur. Le contrôleur est instancié, son constructeur init est lancé.
* La fonction preDispatch est lancée si elle existe juste avant de lancer l'action : par exemple readAction(...).
* Le contrôleur se termine et la fonction postDispatch est lancée.
* La réponse est renvoyée au visiteur.

## Notes

* ↑ Model-View-Controller (MVC), Trygve M. H. Reenskaug - http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html
* ↑ A controller that handles all requests for a Web site., Martin Fowler, http://www.martinfowler.com/eaaCatalog/frontController.html

# Prise en main
## Comment l'utiliser
### Téléchargement

* http://www.zend.com/fr/products/server/downloads.
Si le site propose de créer un compte pour pouvoir télécharger, il faut le faire cela prend moins d'une minute.

### Installation

L'archive du framework se présente sous deux formes :
* full : le framework accompagné de la bibliothèque JavaScript Dojo et des tests unitaires
* minimal : le framework seul
Les composants sont dans library/Zend/
Il suffit de copier le dossier Zend et son contenu sur le serveur à l'emplacement des bibliothèques serveur.
Illustrations :
* Contenu de l'archive.
* Zend à côté des autres bibliothèques serveur.
Il faut mettre à jour la variable include_path du php.ini.

## Configuration Apache

Apache doit avoir le mod_rewrite présent et activé (a2enmode rewrite) ainsi que d'autoriser les directives par .htaccess : « AllowOverride » sera à « All » dans le fichier de configuration du site.

# Mini blog
## Exemple du mini blog.

Une première application après le traditionnel « Hello World! » est de créer un mini blog permettant d'afficher une liste de nouvelles, créer une nouvelle, effacer et la mettre à jour.
Ce premier objet Nouvelle a ainsi 4 actions : ajouter, voir, mettre à jour, effacer. Auxquelles on rajoute l'action voir tous les objets (index).
L'ébauche du contrôleur se présente :
Pour chaque action il existe une vue : un tableau pour index, un formulaire pour ajouter et mettre-à-jour, un formulaire Oui/Non pour effacer.
Le modèle est implémenté par une table SQL nouvelle avec comme attributs (id, titre, corps, date).
La vue générée est un gabarit XHTML habillé par une feuille de style CSS.

## Nouveau projet : monBlog

Dans votre IDE, créez un nouveau projet nommé 'monBlog', l'arborescence de ce projet sera par exemple :
La bibliothèque fournit un script pour créer cette arborescence :
Ce script situé dans le dossier bin/ de la bibliothèque. Sur les systèmes Unix, Il peut être appelé ultérieurement via un alias à placer à la fin de votre ~/.bash_aliases :

# Mini blog/Modèle
## Création dans la base de données

Exemple de création de base de données MySQL :
Exemple de création de table :
La table étant créée il nous faut configurer l'application pour pouvoir y accéder.
Voici, un exemple de configuration pour accéder à la base, il est aussi possible de centraliser la configuration dans un fichier séparé (XML, ini, etc).
Placez les paramètres de connexion dans la fonction initDb de l'initialiseur du bootstrap (application/Bootstrap.php) :
Il est aussi possible de spécifier les paramètres de base de données dans le fichier application/configs/application.ini

## Le modèle

ZF a choisit par défaut la correspondance objet-SQL vers Table(voir aussi : ORM), c'est-à-dire qu'une table SQL est un objet Zend_Db_Table, une ligne est Zend_Db_Table_Row et plusieurs lignes Zend_Db_Table_Rowset.
Pour ajouter cet objet placez-vous dans le dossier application/default/models, puis créez le fichier Nouvelle.php - n'oubliez pas la majuscule - (avec Zend Studio cela se fait par : bouton-droit New/Zend Framework Item/Zend Table) :
Le framework va interroger la base pour connaître les méta-informations associées à la table et de ce fait il va trouver 'id' dans le cas de cette table mais on peut la spécifier avec $_primary.
Le modèle créé, nous allons le charger dans son contrôleur et ensuite des actions.
Sinon, on peut créer un modèle à l'aide de Zend Tool à la racine du projet faire
Ce qui va créer un fichier Nouvelle.php placé dans l’arborescence application\models\DbTable contenant :

## Notes

* ↑ A single instance that handles the business logic for all rows in a database table or view. http://martinfowler.com/eaaCatalog/tableModule.html

# Mini blog/Contrôleur
## Le contrôleur

Les actions par défauts seront la lecture d'une nouvelle, son ajout, sa modification, son effacement et le listing de toutes les nouvelles. Ses différentes actions sont accessibles directement par l'URL :
    http://www.monblog.zf/controlleur/action
Par défaut, c'est le routeur qui réécrit l'URI et redirige vers la bonne action.
    nouvelle/create redirigera vers la bonne page PHP de création de nouvelle. De même le passage de paramètre s'écrit par défaut de la forme :
    nouvelle/read/id/1
Le paramêtre « id » avec la valeur « 1 » sera accessible dans l'action. Idem pour :
    nouvelle/delete/id/123
    nouvelle/update/id/4321
Nous verrons ensuite plus comment personnaliser le routeur pour obtenir une URI plus lisible pour l'humain et les moteurs de recherche.
    nouvelle/read/id/1 peut être réécrite en nouvelle/titre/Premiere_nouvelle
Ce nouvel URI a un titre écrit en français et en clair, c'est pour cela que l'optimisation pour les moteurs de recherche (SEO) peut se faire en parallèle du développement des fonctionnalités d'un site. Avant d'écrire ses actions, la première chose est de charger l'objet dès que l'on instancie le contrôleur. Cela se fait dans le « constructeur » init.
NB: init aulieu de __construct permet de ne pas appeler le constructeur de la super-classe. Sans redéfinition, init est appelée sans aucun paramètre comme dernière instruction de __construct. Notre objet devrait s’appeler Nouvelle comme l'objet qu'il manipule mais il aurait fallu voir immédiatement l'objet Router pour la réécriture d'URL. Ainsi pour des raisons pratiques, le contrôleur s’appellera Index, car dans le monde du web, l'index est la première chose affichée d'un site.
L'objet est chargé et accessible depuis la variable privée de classe $_nouvelles.

## Les actions Create Read Update Delete (CRUD)

Nous avons un contrôleur par objet, l'application va dans un premier temps créer les actions de base : c'est à dire : ajouter (create), lire (read), mettre-à-jour (update), effacer (delete) Cette liste d'action est plus connues sous l'acronyme CRUD (Create, Read, Update, Delete) auxquelles on peut rajouter : lister tous les objets (index) mettre à jour une liste d'objets (updatelist) effacer une liste d'objets (deletelist) Ces actions couvre le spectre des actions possible pour un objet mais l'application se devra aussi de pouvoir ajouter une nouvelle action ou d'invalider une existante. L'ordre d'explication des actions sera croissante en difficulté :
* read : lire un enregistrement et l'afficher
* create : formulaire d'ajout d'enregistrement
* index : liste de tous les enregistrements
* update : formulaire de modification
* delete : effacement d'un objet

# Mini blog/Actions
## L'action lire (read)

Cette action prend l'identifiant de l'objet comme paramètre. Ce paramètre est envoyé dans l'URL par la méthode Http Get. Cet identifiant sert ensuite à consulter l'objet par la méthode find(..) :
L'objet est ensuite transformé en tableau pour être envoyé à la vue :
Cela donne dans le contrôleur la nouvelle action :
La vue sera une simple liste à puce, à insérer dans :
    application/default/views/scripts/index/read.phtml
Cet action est accessible maintenant par l'URL :
    http://www.monblog.zf/index/read/id/777
L'affichage ne produira qu'un NULL car nous n'avons pas encore enregistré de données. On peut tester en insérant des données directement en base comme ici :
On peut aussi ajouter l'action create et sa vue.

## L'action ajouter (create)

Cette action ajoute un nouvel enregistrement en deux étapes : le formulaire vide est affiché, l'utilisateur saisie les données puis soumet le formulaire. Chaque élément possède un Validateur. Par exemple si l'utilisateur doit saisir un champ requis et qu'il soumet le formulaire sans avoir bien rempli ce champ, le formulaire est réaffiché pré-rempli avec les données précédemment saisies et un message d'erreur est affiché à côté du champ fautif.
Le Framework propose ainsi un service pour examiner la conformité des données : caractères numériques, alpha-numériques, dates, adresse e-mail, type de fichier et avec la possibilité de personnaliser son propre validateur.
La première étape est la création du formulaire, en considérant qu'il s'agit d'un objet fortement lié au modèle on va créer le fichier dans le dossier des modèles. Une autre approche est de considérer ce formulaire comme un objet utilisateur et de créer le fichier dans library/My/Forms/. Dans application/default/models/NouvelleForm.php :
La deuxième étape est la logique de gestion du formulaire dans l'action create :
La vue associée dans application/default/views/scripts/index/create.phtml :
Maintenant on peut vérifier l'affichage de la nouvelle. Il faut noter auparavant l'id dans la base de donnée et ensuite appeler l'action read :
    index/read/id/341

## L'action lister tous les objets (index)

Cette action liste tous les enregistrements d'un objets sous forme d'un tableau. Il y en a un par ligne. La logique dans l'action est beaucoup plus simple que celle dans 'create' par contre l'affichage des objets sera moins trivial.
fetchAll retourne un objet Rowset et c'est affecté à la variable de vue $nouvelles.
Ainsi dans la vue Html, $nouvelles sera par exemple :
Il y a ici un objet Rowset contenant deux objets, que l'on affichera sous forme de lignes de tableau. Chaque colonne correspondant a un attribut. La vue associée sera donc un tableau dynamique car l'on ne connait pas à l'avance le nombre de colonnes.
En résumé, on construit l'en-tête (thead), le pied (tfoot) puis finalement les données du tableau (tbody). Pour une lecture aisée, la liste des objets peut être découpée en pages, un formulaire permet de choisir le nombre d'objets par page. En utilisant le composant Zend_Paginator qui s'appuie sur les sessions PHP pour mémoriser les choix du client.

## L'action mettre-à-jour (update)

Cette action prend un identificateur en paramètre, vérifie que les données du formulaire sont valides puis va mettre-à-jour un seul enregistrement. Le même formulaire que 'create' est utilisé sauf qu'il est pré-rempli avec les attributs de l'enregistrement à modifier. La logique de cette action est très proche de create. Cette fois-ci on récupère l'id en paramètre GET, et on pré-remplit un formulaire. Par contre s'il y a des données POST, c'est que l'utilisateur a soumis le formulaire, dans ce cas nous mettons à jour l'enregistrement. La première étape est d'écrire les branchements sans mise-à-jour du modèle :
La seconde et dernière étape est de compléter avec la mise-à-jour du modèle :
Les données postées sont nettoyées des données non pertinentes au modèle (valeur du bouton 'submit'). On exécute ensuite la requête de mise-à-jour. Il faut garder à l'esprit que les données provenant des paramètres d'URL comme 'id' doivent être contrôlées pour éviter tous problèmes de sécurité. La vue est la même que pour 'create', ainsi dans application/default/views/scripts/index/update.phtml :
Il faut par contre modifier la vue 'index' pour y ajouter une colonne 'modifier' dans les nœuds thead et tfoot :
Dans le nœud tbody ce sera un lien vers l'objet avec son id en paramètre :
Pour que le lien vers l'URI aboutisse il est souvent conseillé d'utiliser la balise 'Base' dans l'en-tête Html :
Pour terminer ce tour d'horizon des actions de base, il reste l'action d'effacement : 'delete'.

## L'action effacer (delete)

Cette action prend l'identifiant comme paramètre et se déroule en deux temps : au premier appel l'objet à effacer est affiché suivit d'un formulaire avec boutons pour confirmer ou non l'effacement. Si l'utilisateur clique sur 'Non', il est redirigé vers l'action 'index' qui liste tous les enregistrement de l'objet courant. Dans le cas de la confirmation, l'objet est effacé.
La première étape est de créer le formulaire de confirmation ainsi l'action delete peut s'écrire ainsi :
Ici le formulaire est programmé mais il aurait pu être tout autant créé directement en Html dans la vue. La vue s'en trouve d'ailleurs ici réduite au minimum :
On doit maintenant ajouter la logique d'effacement :
Pour compléter, la vue on récapitule les attributs de la nouvelle. On copie/colle le code source de la vue 'read' à la suite du formulaire ce qui au final est :
Il faut comme cela l'a été pour 'update' modifier la vue 'index' pour y ajouter une colonne 'supprimer' dans les nœuds thead et tfoot :
Dans le nœud tbody ce sera un lien vers l'objet avec son id en paramètre :
D'autres actions sont envisageables comme les actions d'effacement (deletelist) ou de modification de masse (updatelist) mais cela dépasse le cadre de ce tutoriel.

# Mini blog/URL
## Réécriture d'URL, SEO, Zend_Router.

Actuellement l'URI de lecture d'une nouvelle est en anglais et a des paramètres numériques :
    index/read/id/1
Ceci a deux inconvénients, un moteur de recherche va par exemple mal indexer nos articles pour des recherches en français. L'utilisation d'id numériques est pratique mais n'a aucune valeur pour l'indexation. Les sites avec un rang d'indexation élevé ont des URI explicites comme :
    index/fr/article/L'automne-est-de-retour
La première étape est de tester une redirection d'URL plus simple comme :
    index/read/id/714 vers : nouvelle/714
Dans le Bootstrap il suffira d'ajouter (ou dans Initializer.php : initRoutes ) :
Avec $this->_front l'instance du Zend_Controller_Front. Qui est normalement déjà disponible si l'on a créé un projet ZF avec un EDI, sinon il faut rajouter :
La nouvelle route étant créé nous pouvons modifier la vue de l'index pour rajouter un lien vers une nouvelle lorsque l'on clique sur le titre. Dans le nœud tbody de la vue 'application/default/views/scripts/index/index.phtml' :
L'aide de vue (View Helper) Url construit automatiquement l'URL réécrite, on peut ainsi changer ad nauseam.
La deuxième étape est de modifier cette route pour y intégrer le titre de la nouvelle. Le titre de la nouvelle est une phrase, il nous faut détecter cette phrase à l'aide de l'expression régulière.

# Conclusion

Ce rapide tour d'horizon du cadriciel en utilisant l'exemple simple d'une gestion de nouvelle a montré les avantages de cette nouvelle méthode de programmation et la part grandissante des patrons de conceptions dans le développement web moderne.
Il est recommandé de consulter les livres traitant ces sujets en profondeur, de se familiariser avec la documentation officielle et d'établir une veille technologique par l'abonnement aux forums, blogs des développeurs.

## Webographie

* La documentation : http://framework.zend.com/manual/fr/
* L'API : http://framework.zend.com/apidoc/core/
* Le forum francophone : http://www.z-f.fr
Et aussi :
* « Programmation PHP », œuvre collective. - Wikibooks.
* « Cours PHP », œuvre collective. - Wikiversity, département de la Programmation informatique.

## Bibliographie

* français « Développement Php avec le Zend Framework » : Julien Pauli. - Eyrolles, Cahiers du programmeur. - 400 pages.
* anglais « Zend Framework in Action » : Rob Allen. – Manning Publications. – 425 pages ; http://www.manning.com/allen/