Créer une layout

Créer un modèle et une table en base de données

Avant de démarrer, considérons ceci: où vont se trouver ces classes et comment les retrouver? Le projet par défaut que nous avons conçu instancie un autoloader. Nous pouvons lui attacher d'autres autoloaders pour qu'il puisse trouver des classes différentes. Typiquement nous voulons que nos classes MVC soient groupées sous une même arborescence -- dans ce cas, application/ -- et nous utiliserons un préfixe commun.

Zend_Controller_Front a une notion de "modules", qui sont des mini-applications individuelles. Les modules reflètent la structure de répertoires que la commande zf crée sous application/, et toutes les classes à l'intérieur sont supposées commencer par un préfixe étant le nom du module. application/ est lui-même un module -- le module "default" ou "application". Ainsi, nous allons vouloir configurer un autoload pour les ressources sous ce dossier.

Zend_Application_Module_Autoloader propose la fonctionnalité nécessaire à la correspondance entre les ressources d'un module et ses dossiers, il propose pour cela un mécanisme de nommage standard. Une instance de la classe est créee par défaut pendant l'initialisation de l'objet de bootstrap et utilisera le préfixe de module "Application". De ce fait, nos classes de modèles, formulaires, et tables commenceront toutes par le préfixe de classe "Application_".

Maintenant voyons de quoi est fait un livre d'or. Typiquement il existe simplement une liste d'entrées avec un commentaire, timestamp, et souvent une adresse email. En supposant que nous stockons cela dans une base de données, nous aurons aussi besoin d'un identifiant unique pour chaque entrée. Nous voudrons aussi sauvegarder une entrée, récupérer une entrée individuelle ou encore récupérer toutes les entrées. De ce fait, l'API du modèle d'un simple livre d'or ressemblerait à ceci:

  1. // application/models/Guestbook.php

__get() et __set() nous simpliferons l'accès aux attributs et proxieront vers les autres getters et setters. Ils nous permettront de même de nous assurer que seuls les attributs que nous avons définis seront accessibles dans l'objet.

find() et fetchAll() permettent de récupérer une seule entrée ou toutes les entrées alors que save() offrira la possibilité de stocker une entrée dans le support de stockage.

Maintenant à partir de là, nous pouvons commecer à penser en terme de base de données.

Nous devons d'abord intialiser une ressource Db. Comme pour les ressources Layout et View, nous pouvons utiliser de la configuration pour Db. Cela est possible au moyen de la commande zf configure db-adapter:

  1. % zf configure db-adapter \
  2. > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' \
  3. > production
  4. A db configuration for the production has been written to the application config file.
  5.  
  6. % zf configure db-adapter \
  7. > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-testing.db"' \
  8. > testing
  9. A db configuration for the production has been written to the application config file.
  10.  
  11. % zf configure db-adapter \
  12. > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-dev.db"' \
  13. > development
  14. A db configuration for the production has been written to the application config file.

Editez maintenant le fichier application/configs/application.ini, vous verrez que les lignes suivantes ont été ajoutées dans les sections appropriées:

  1. ; application/configs/application.ini
  2.  
  3. [production]
  4. ; ...
  5. resources.db.adapter = "PDO_SQLITE"
  6. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
  7.  
  8. [testing : production]
  9. ; ...
  10. resources.db.adapter = "PDO_SQLITE"
  11. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
  12.  
  13. [development : production]
  14. ; ...
  15. resources.db.adapter = "PDO_SQLITE"
  16. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"

Votre fichier de configuration final devrait ressembler à ceci:

  1. ; application/configs/application.ini
  2.  
  3. [production]
  4. phpSettings.display_startup_errors = 0
  5. phpSettings.display_errors = 0
  6. bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
  7. bootstrap.class = "Bootstrap"
  8. appnamespace = "Application"
  9. resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
  10. resources.frontController.params.displayExceptions = 0
  11. resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
  12. resources.view[] =
  13. resources.db.adapter = "PDO_SQLITE"
  14. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
  15.  
  16. [staging : production]
  17.  
  18. [testing : production]
  19. phpSettings.display_startup_errors = 1
  20. phpSettings.display_errors = 1
  21. resources.db.adapter = "PDO_SQLITE"
  22. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
  23.  
  24. [development : production]
  25. phpSettings.display_startup_errors = 1
  26. phpSettings.display_errors = 1
  27. resources.db.adapter = "PDO_SQLITE"
  28. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"

Notez que la/les base(s) de données seront stockées sous data/db/. Créez ces dossiers et affectez leur les bons droits. Sur les systèmes Unix utilisez:

  1. % mkdir -p data/db; chmod -R a+rwX data

Sur Windows, vous devrez créer le dossier avec l'explorateur et lui donner les bonnes permissions pour que tout le monde puisse y écrire.

Dès lors, nous possédons une connexion à une base de données, dans notre cas il s'agit de Sqlite et la base est placée sous le dossier application/data/. Créons maintenant une table pour stocker nos entrées de livre d'or.

  1. -- scripts/schema.sqlite.sql
  2. --
  3. -- You will need load your database schema with this SQL.
  4. 'noemail@test.com'"id""guestbook" ("id");

Puis pour ne pas travailler dans le vide, créons quelques enregistrements de départ.

  1. -- scripts/data.sqlite.sql
  2. --
  3. -- You can begin populating the database with the following SQL statements.
  4. 'ralph.schindler@zend.com',
  5.     'Hello! Hope you enjoy this sample zf application!',
  6.     DATETIME('NOW''foo@bar.com',
  7.     'Baz baz baz, baz baz Baz baz baz - baz baz baz.',
  8.     DATETIME('NOW'));

Maintenant que nous avons la définition de la base de données ainsi que des données, créons un script qui pourra être lancé pour entièrement initialiser la base de données de manière autonomme. Bien sûr cela ne sera pas nécessaire en production. Créez le script scripts/load.sqlite.php avec le contenu suivant:

  1. // scripts/load.sqlite.php
  2.  
  3. /**
  4. * Script pour créer et charger la base
  5. */
  6.  
  7. // Initialise le chemin vers l'application et l'autoload
  8. 'APPLICATION_PATH''APPLICATION_PATH''/../application''/../library''Zend/Loader/Autoloader.php'// Definit des options CLI
  9. 'withdata|w' => 'Load database with sample data',
  10.     'env|e-s'    => 'Application environment for which to create database (defaults to development)',
  11.     'help|h'     => 'Help -- usage message'// Mauvaises options passées: afficher l'aide
  12. // Si l'aid eest demandée, l'afficher
  13. 'h'// Initialise des valeurs selon la présence ou absence d'options CLI
  14. 'w''e''APPLICATION_ENV''APPLICATION_ENV''development' : $env);
  15.  
  16. // Initialise Zend_Application
  17. '/configs/application.ini'
  18. );
  19.  
  20. // Initialise et récupère la ressoucre DB
  21. $bootstrap = $application->getBootstrap();
  22. $bootstrap->bootstrap('db');
  23. $dbAdapter = $bootstrap->getResource('db');
  24.  
  25. // Informons l'utilisateur de ce qui se passe (nous créons une base de données
  26. // ici)
  27. 'testing''Writing Database Guestbook in (control-c to cancel): '"\r"// Vérifions si un fichier pour la base existe déja
  28. 'resources''db']['params']['dbname'// Chargement du fichier de la base de données.
  29. '/schema.sqlite.sql');
  30.     // utilise la connexion directement pour charger le sql
  31. 'testing''Database Created''/data.sqlite.sql');
  32.         // utilise la connexion directement pour charger le sql
  33. 'testing''Data Loaded.''AN ERROR HAS OCCURED:'// Ce script sera lancé depuis la ligne de commandes

Exécutons ce script. Depuis un terminal ou un invite DOS, effectuez:

  1. % php scripts/load.sqlite.php --withdata

Vous devriez voir ceci:

  1. path/to/ZendFrameworkQuickstart/scripts$ php load.sqlite.php --withdata
  2. Writing Database Guestbook in (control-c to cancel):
  3. 1
  4. Database Created
  5. Data Loaded.

Nous avons maintenant une base de données et une table pour notre application de livre d'or. Les prochaines étapes seront de créer le code applicatif. Ceci incluera une source de données (dans notre cas nous utiliserons Zend_Db_Table), un datamapper pour connecter cette source à notre modèle et enfin un contrôleur pour intéragir avec le modèle et afficher du contenu divers.

Nous allons utiliser un » Table Data Gateway pour se connecter à notre source de données; Zend_Db_Table propose cette fonctionnalité. Créons les classes basées sur Zend_Db_Table. Comme nous avons opéré pour les layouts ou la base, nous pouvons utiliser la commande zf pour nous aider, avec la commande complète create db-table. Celle-ci prend deux arguments au minimum, le nom de la classe à créer et la table qui y fera référence.

  1. % zf create db-table Guestbook guestbook
  2. Creating a DbTable at application/models/DbTable/Guestbook.php
  3. Updating project profile 'zfproject.xml'

En regardant l'orborescence du projet, un nouveau dossier application/models/DbTable/ a été crée contenant le fichier Guestbook.php. Si vous ouvrez ce fichier, vous y verrez le contenu suivant:

  1. // application/models/DbTable/Guestbook.php
  2.  
  3. /**
  4. * This is the DbTable class for the guestbook table.
  5. *//** Table name */'guestbook';
  6. }

Notez le préfixe de classe: Application_Model_DbTable. Le premier segment est "Application", le nom du module, puis vient le nom du composant "Model_DbTable" qui est lié au dossier models/DbTable/ du module.

Pour étendre Zend_Db_Table, seuls un nom de table et éventuellement un nom de clé primaire (si ce n'est pas "id") sont nécessaires.

Créons maintenant un » Data Mapper. Un Data Mapper fait correspondre un objet métier à la base de données. Dans notre cas Application_Model_Guestbook vers la source de données Application_Model_DbTable_Guestbook. Une API typique pour un data mapper est:

  1. // application/models/GuestbookMapper.php

En plus de ces méthodes nous allons ajouter des méthodes pour affecter/récupérer l'objet Table Data Gateway. Pour créer la classe initiale, utilsez l'outil CLI zf:

  1. % zf create model GuestbookMapper
  2. Creating a model at application/models/GuestbookMapper.php
  3. Updating project profile '.zfproject.xml'

Maintenant, éditez la classe Application_Model_GuestbookMapper dans application/models/GuestbookMapper.php pour y voir ceci:

  1. // application/models/GuestbookMapper.php
  2. 'Invalid table data gateway provided''Application_Model_DbTable_Guestbook''email''comment' => $guestbook->getComment(),
  3.             'created''Y-m-d H:i:s''id''id = ?'

Maintenant il faut créer la classe de modèle. Une fois de plus, nous utiliserons la commande zf create model:

  1. % zf create model Guestbook
  2. Creating a model at application/models/Guestbook.php
  3. Updating project profile '.zfproject.xml'

Nous allons modifier cette classe PHP vide pour simplifier le remplissage du modèle via un tableau dans le constructeur ou une méthode setOptions(). Le code final de la classe de modèle stockée dans application/models/Guestbook.php devrait ressembler à ceci:

  1. // application/models/Guestbook.php
  2. 'set''mapper''Invalid guestbook property''get''mapper''Invalid guestbook property''set'

Enfin, pour connecter tous ces éléments ensemble, créons un contrôleur qui listera les entrées de la base de données.

Pour créer le nouveau contrôleur, utilisez la commande zf create controller:

  1. % zf create controller Guestbook
  2. Creating a controller at
  3.     application/controllers/GuestbookController.php
  4. Creating an index action method in controller Guestbook
  5. Creating a view script for the index action method at
  6.     application/views/scripts/guestbook/index.phtml
  7. Creating a controller test file at
  8.     tests/application/controllers/GuestbookControllerTest.php
  9. Updating project profile '.zfproject.xml'

Ceci va créer GuestbookController dans application/controllers/GuestbookController.php, avec une seule action indexAction(). Un script de vue sera aussi crée pour ce contrôleur, il sera logé dans application/views/scripts/guestbook/, avec une vue pour l'action index.

Nous allons utiliser l'action "index" pour lister toutes les entrées du livre d'or.

Un aterrissage sur indexAction() devra lister toutes les entrées du livre d'or. Ceci ressemblera à ce qui suit:

  1. // application/controllers/GuestbookController.php

Et bien sûr un script de vue sera nécessaire. Editez application/views/scripts/guestbook/index.phtml pour y inclure ceci:

  1. <!-- application/views/scripts/guestbook/index.phtml -->
  2.  
  3. <p><a href="<?php echo $this->url(
  4.     array(
  5.         'controller' => 'guestbook',
  6.         'action'     => 'sign'
  7.     ),
  8.     'default',
  9.     true) ?>"

Note: Checkpoint
Naviguez maintenant vers "http://localhost/guestbook". Vous devriez voir ceci apparaitre dans votre navigateur:

learning.quickstart.create-model.png

Note: Utiliser le script de chargement des données
Le script de chargement des données montré dans la section en question (scripts/load.sqlite.php) peut être utilisé pour créer une base de données pour chaque environnement défini et la remplir de données d'exemple. En interne, il utilise Zend_Console_Getopt, qui permet de préciser des options à la commande. Si vous passez "-h" ou "--help", toutes les options disponibles seront affichées:

  1.  
L'option "-e" permet de préciser la valeur de la constante APPLICATION_ENV -- ce qui en effet permet de créer une base de données SQLite pour chaque environnement défini. N'oubliez pas l'envrionnement lorsque vous utilisez ce script.


Créer une layout