Doctrine et le Zend Framework : Présentation, intégration et utilisationCréer automatiquement les relations objets - base de données. |
samedi 03 septembre 2011 à 16:13
|
Le but de ce tutoriel est de présenter l'ORM Doctrine et de l'intégrer dans le Zend Framework.
Quelques définitions
- ORM : Le Mapping d'Objet Relationnel (Object-Relational Mapping) est une technique de programmation informatique qui donne l'illusion d'une base de données orientée objet à partir d'une base de données relationnelle en définissant des correspondances entre cette base de données et les objets du langage utilisé. C'est un travail long et fastidieux de devoir créer ces objets à la main, surtout si la base de données est conséquente et change régulièrement.
- Modèle : Dans le design pattern MVC, le modèle est la partie qui contient ou décrit les données. La plupart du temps le modèle est un ensemble de classes qui permet la relation avec une base de données.
Présentation de Doctrine
Doctrine est l'un des meilleurs ORM existants à ce jour. Sa notoriété et ses compétences ont fait de lui l'ORM par défaut du framework Symfony.
Le Zend Framework est le framework utilisé pour le développement d'Informatix. Il possède un composant (Zend_Db) qui permet de lancer des requêtes vers une BDD, néanmoins ce composant n'est pas un générateur ORM (toutes les classes du modèle doivent toujours être faites à la main) et il a quelques limitations.
Des limitations ? Eh oui ! lors du développement d'Informatix (qui n'est pourtant pas un projet complexe) j'ai eu le malheur de constater que Zend_Db était dans l'incapacité d'exécuter certaines de mes requêtes
(ne me demandez pas lesquelles, je ne m'en souviens plus).
Ayant quelques connaissances en Symfony, je me suis rappelé du mode de fonctionnement de son modèle et de son extraordinaire ORM. J'ai par la suite décidé d'adopter Doctrine, il ne me restait plus qu'à réussir à l'intégrer dans le Zend Framework.
Notez qu'il est prévu que Doctrine devienne aussi l'ORM du Zend Framework dans les prochaines versions.
Intégration de Doctrine dans le Zend Framework
La première chose à faire est de télécharger Doctrine. J'utilise actuellement la version 1.2.4, ce n'est pas la dernière version et je ne pense pas que les manipulations qui vont suivre fonctionnent toutes avec les versions postérieures.
Placez le fichier "Doctrine.php" et le répertoire "Doctrine" dans le dossier "library" de votre application, aux côtés des répertoires "Zend" et "ZendX".
Créez l'arborescence de dossiers suivante :
Il faut maintenant créer la variable d'environnement APPLICATION_MODELS. La solution la plus simple est de l'ajouter dans l'index à la suite des autres déclarations.
/public/index.php
/* Utile pour Doctrine */
defined('APPLICATION_MODELS')
|| define('APPLICATION_MODELS', (getenv('APPLICATION_MODELS') ? getenv('APPLICATION_MODELS') : APPLICATION_PATH.'/models'));
Il y a bien sûr une petite phase de configuration dans laquelle nous indiquons l'arborescence créée précédemment.
/application/configs/application.ini
doctrine.data_fixtures_path = APPLICATION_PATH "/doctrine/data/fixtures" doctrine.models_path = APPLICATION_PATH "/models" doctrine.migrations_path = APPLICATION_PATH "/doctrine/migrations" doctrine.sql_path = APPLICATION_PATH "/doctrine/data/sql" doctrine.yaml_schema_path = APPLICATION_PATH "/doctrine/schema" ; on génère les classes de table doctrine.generate_models_options.generateTableClasses = true ; Définition de la Data Source Name. ; Evidemment il faut remplacer les mots en majuscules par vos propres valeurs. ; Par exemple pour MySQL. doctrine.dsn = "mysql://LOGINASS@URL/BASE"
Comme pour beaucoup de composants avec Zend Framework, il nous faut l'initialiser. C'est sûrement la partie la plus compliquée de ce tutoriel, je vous demande de me faire confiance et de copier-coller bêtement pour le moment. Direction le bootstrap.
/application/Bootstrap.php
protected function _initDoctrine()
{
/* On met Doctrine en autoload */
$this->getApplication()
->getAutoloader()
->pushAutoloader ( array ('Doctrine', 'autoload' ) );
spl_autoload_register(array('Doctrine', 'modelsAutoload'));
/* On récupère une instance de Doctrine */
$manager = Doctrine_Manager::getInstance ();
/* Permet de valider automatiquement l'intégrité des données
** ce qui veut dire que l'on ne peut pas mettre une variable de type string
** dans un champs de type int.
*/
$manager->setAttribute (Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
/* AUTO_ACCESSOR_OVERRIDE va nous permettre de personnaliser l'assignation de données. */
$manager->setAttribute ( Doctrine::ATTR_AUTO_ACCESSOR_OVERRIDE, true );
/* Doctrine permet de personnaliser également les classes de table en permettant
** de créer des méthodes propres à une table.
**
** Ce paramètre permet de charger le fichier contenant nos méthodes personnalisées.
*/
$manager->setAttribute (
Doctrine::ATTR_MODEL_LOADING,
Doctrine::MODEL_LOADING_CONSERVATIVE
);
/* On permet le chargement des classes de table. */
$manager->setAttribute ( Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true );
$doctrineConfig = $this->getOption('doctrine');
Doctrine::loadModels($doctrineConfig['models_path']);
$conn = Doctrine_Manager::connection($doctrineConfig['dsn'],'doctrine');
$conn->setAttribute(Doctrine::ATTR_USE_NATIVE_ENUM,true);
$conn->setCharset('utf8');
$conn->setCollate('utf8_general_ci');
return ($conn);
}
Pour finir il nous faut un script pour communiquer avec Doctrine et exécuter des actions. Ce script lancera la CLI (l'interface de lignes de commandes) de Doctrine et nous permettra de lui passer des paramètres.
/application/scripts/Doctrine-cli.php
/*
** Comme vous pouvez le voir la majorité de ce code est le même que dans
** /public/index.php.
*/
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/..'));
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'devlocal'));
/* Utile pour Doctrine */
defined('APPLICATION_MODELS')
|| define('APPLICATION_MODELS', (getenv('APPLICATION_MODELS') ? getenv('APPLICATION_MODELS') : APPLICATION_PATH.'/models'));
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
require_once 'Doctrine.php';
/** Zend_Application */
require_once 'Zend/Application.php';
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
date_default_timezone_set('Europe/Berlin');
$application->getBootstrap()->bootstrap('doctrine'); /* Initialisation de Doctrine */
$config = $application->getOption('doctrine');
$cli = new Doctrine_Cli($config);
$cli->run($_SERVER['argv']);
Pour utiliser notre CLI :
Lancement du générateur de classes
NlC0@informatix : cd /application/scripts php5 Doctrine-cli.php generate-models-db # Création des classes du modèle php5 Doctrine-cli.php # Permet de voir toutes les options possibles.
Après la génération, vous devriez avoir dans le dossier "/application/models" :
- Des fichiers {nom de table}.php.
- Des fichiers {nom de table}Table.php.
- Un dossier "generated" contenant des fichiers Base{nom de table}.php.
Et voilà c'est fini pour l'intégration. Ouf !
Utilisation de Doctrine
Doctrine utilise un langage appelé DQL (Doctrine Query Langage). C'est un langage très simple qui permet de faire des requêtes SQL complexes.
Voici des exemples :
Exemples d'utilisation de Doctrine
/* Si j'ai une table "auteur" avec un champ "nom" */
/* Avec les finders magiques. */
$auteur = Doctrine_Core::getTable('Auteur')->findOneByNom($nom);
/* Avec du DQL. */
$auteurs = Doctrine::getTable('Auteur')
->createQuery('a')
->where('a.nom = ?', $nom)
->orderby('a.nom ASC')
->execute()
J'espère qu'après avoir lu ceci vous gagnerez en temps de développement.
Pour la moindre question ou remarque n'hésitez pas à laisser un commentaire.
|
AuteurNicolas GAUTRONCréateur et administrateur. http://www.informatix.fr |
Dans la même catégorie
Une version mobile de mon site avec le Zend FrameworkCréer son flux RSS simplement avec Zend_Feed
Un client HTTP / proxy en PHP
Appliquer un layout sur un mail avec le Zend Framework
Activer PHP5 sur un hébergement 1&1
Comment lancer une requête multi-bases avec les fonctions MySQL ?
Implode / Explode : Du tableau à la chaine de caractères, de la chaine de caractères au tableau


ASS@URL/BASE"