BLOG

[PHP] CodeIgniter - Intégrer Doctrine 2

 

Par défaut, CodeIgniter n'est fourni avec aucun ORM, uniquement avec Active REcord, qui n'est pas du tout ORM, simplement des classes générant derrière les requêtes SQL.

 

Aujourd'hui un petit tuto qui va vous permettre d'intégrer assez facilement Doctrine 2 dans votre application favorite !

 

PRE REQUIS

- CodeIgniter 2.x.x installé et configuré

- Doctrine 2.x téléchargeable ici

Pour ma part j'ai testé sur la 2.0 et 2.1, la 2.2 étant maintenant stable ça devrait fonctionner aussi !

- Etre en PHP > 5.3 (pour l'utilisation des namespaces

- Et ... c'est tout !

 

INSTALLATION

1/ Extraire l'archive (sauf si vous êtes passé par GitHub ou PEAR, à ce moment là vos focihiers sont déjà extraits.

2/ Copier le dossier Doctrine et son contenu dans application/libraries/ de votre application CI

3/ Créer un fichier Doctrine.php dans application/libraries/ et y créer la classe suivante :

class Doctrine
{
    // the Doctrine entity manager
    public $em = null;

    public function __construct()
    {
        
        // include our CodeIgniter application's database configuration
        require APPPATH.'config/database.php';
       
        // include Doctrine's fancy ClassLoader class
        require_once APPPATH.'libraries/Doctrine/Common/ClassLoader.php';
        

        // load the Doctrine classes
        $doctrineClassLoader = new \Doctrine\Common\ClassLoader('Doctrine', APPPATH.'libraries');
        $doctrineClassLoader----------->register();
       
        // load Symfony2 helpers
        // Don't be alarmed, this is necessary for YAML mapping files
        $symfonyClassLoader = new \Doctrine\Common\ClassLoader('Symfony', APPPATH.'libraries/Doctrine');
        $symfonyClassLoader->register();

        // load the entities
        $entityClassLoader = new \Doctrine\Common\ClassLoader('Entities', APPPATH.'models');
        $entityClassLoader->register();

        // load the proxy entities
        $proxyClassLoader = new \Doctrine\Common\ClassLoader('Proxies', APPPATH.'models');
        $proxyClassLoader->register();
        
        // set up the configuration
        $config = new \Doctrine\ORM\Configuration;
   
        if(ENVIRONMENT == 'development') {
            // set up simple array caching for development mode
            $cache = new \Doctrine\Common\Cache\ArrayCache;
        } else {
            // set up caching with APC for production mode
            //$cache = new \Doctrine\Common\Cache\ApcCache;
        }
        $config->setMetadataCacheImpl($cache);
        $config->setQueryCacheImpl($cache);

        // set up proxy configuration
        $config->setProxyDir(APPPATH.'models/Proxies');
        $config->setProxyNamespace('Proxies');
       
        // auto-generate proxy classes if we are in development mode
        $config->setAutoGenerateProxyClasses(ENVIRONMENT == 'development');

        // set up annotation driver
        $yamlDriver = new \Doctrine\ORM\Mapping\Driver\YamlDriver(APPPATH.'models/Mappings');
        $config->setMetadataDriverImpl($yamlDriver);

        // Database connection information
        $connectionOptions = array(
            'driver' => 'pdo_mysql',
            'user' => $db['default']['username'],
            'password' => $db['default']['password'],
            'host' => $db['default']['hostname'],
            'dbname' => $db['default']['database']
        );
       
        // create the EntityManager
        $em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
       
        // store it as a member, for use in our CodeIgniter controllers.
        $this->em = $em;
    }
}

Cette lib va tout simplement se charger de loader tous les bons modules de Doctrine, en utilisant la configuration de votre DB faite dans le fichier config/database.php

4/ Auto loader la lib précédemment créée, en rajoutant dans config/autoload.php, 'doctrine' à l'array $autoload['libraries']

 

CREER SES MODELS

Ensuite il va maintenant falloir crééer ses Models correspondant à sa DB.

Si votre DB existe déja, vous pourrez utiliser la fonction convert-mapping de l'outil en ligne de commande pour générer les fichiers correspondants sans tout refaire à la main.

Doctrine fonctionne sur un principe de Models YAML, voici l'exemple de fichier YAML pour une table User que j'utilise :

Entities\User:
  type: entity
  table: user
  fields:
    userId:
      id: true
      type: integer
      unsigned: false
      nullable: false
      column: user_id
      generator:
        strategy: IDENTITY
    userName:
      type: string
      length: 255
      fixed: false
      nullable: false
      column: user_name
    userPassword:
      type: string
      length: 255
      fixed: false
      nullable: false
      column: user_password
    userEmail:
      type: string
      length: 255
      fixed: false
      nullable: false
      column: user_email
    userRights:
      type: integer
      unsigned: false
      nullable: false
      column: user_rights
  lifecycleCallbacks: {  }

Tous vos Models doivent être précédés de Entities\ (ici Entities\User à la 1ère ligne), je vous laisse vous reporter à la documentation Doctrine de votre version choisie pour voir tous les champs possible.

Créez un dossier Mappings dans application/models/ et mettez y vos models en les nommant Entities.XXX.dcm.yml (où XXX est le nom de votre table et/ou model)

Par la même occasion, crééez deux dossier Entities et Proxies toujours dans application/models/

 

OUTIL DOCTRINE EN LIGNE DE COMMANDE

Il vous faut maintenant mettre en place l'outil en ligne de commande pour la génération des models PHP, de la structure de la db, ...

Créer un fichier doctrine-cli.php dans le dossier application/ et collez y le code suivant :

require APPPATH.'libraries/Doctrine.php';

$doctrine = new Doctrine();
 
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
    'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($doctrine->em->getConnection()),
    'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($doctrine->em)
));

$cli = new \Symfony\Component\Console\Application('Doctrine Command Line Interface (CodeIgniter integration by Joel Verhagen)', Doctrine\ORM\Version::VERSION);
$cli->setCatchExceptions(true);
$cli->setHelperSet($helperSet);
$cli->addCommands(array(
// DBAL Commands
new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
 
// ORM Commands
new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),

));
$cli->run();

En ligne de commande exécutez : php doctrine-cli.php, vous verrez alors toutes les commandes possible pour Doctrine :

Doctrine Command Line Interface (CodeIgniter integration by Joel Verhagen) version 2.0.5

Usage:
  [options] command [arguments]

Options:
  --help           -h Display this help message.
  --quiet          -q Do not output any message.
  --verbose        -v Increase verbosity of messages.
  --version        -V Display this program version.
  --ansi           -a Force ANSI output.
  --no-interaction -n Do not ask any interactive question.

Available commands:
  help                         Displays help for a command (?)
  list                         Lists commands
dbal
  :import                      Import SQL file(s) directly to Database.
  :run-sql                     Executes arbitrary SQL directly from the command line.
orm
  :convert-d1-schema           Converts Doctrine 1.X schema into a Doctrine 2.X schema.
  :convert-mapping             Convert mapping information between supported formats.
  :ensure-production-settings  Verify that Doctrine is properly configured for a production environment.
  :generate-entities           Generate entity classes and method stubs from your mapping information.
  :generate-proxies            Generates proxy classes for entity classes.
  :generate-repositories       Generate repository classes from your mapping information.
  :run-dql                     Executes arbitrary DQL directly from the command line.
  :validate-schema             Validate that the mapping files.
orm:clear-cache
  :metadata                    Clear all metadata cache of the various cache drivers.
  :query                       Clear all query cache of the various cache drivers.
  :result                      Clear result cache of the various cache drivers.
orm:schema-tool
  :create                      Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.
  :drop                        Drop the complete database schema of EntityManager Storage Connection or generate the corresponding SQL output.
  :update                      Processes the schema and either update the database schema of EntityManager Storage Connection or generate the SQL output.

 

Il ne vous reste plus qu'à générer tous les models grâce à cet outil :

php doctrine-cli.php orm:generate-entities models

Ainsi que les proxies :

php doctrine-cli.php orm:generate-proxies

Enfin, on vide la DB (si elle n'est pas déja vide) et la recréé à partir des fichiers yml créés précédemment :

php doctrine-cli.php orm:schema-tool:drop --force
php doctrine-cli.php orm:schema-tool:create

 

UTILISATION

Prenons l'exemple d'une table nommée User, avec des champs de base (id, email, nickname), voici comment créer un User :

$user = new Entities\User;
$user->setNickname('Mon pseudo');
$user->setEmail('pseudo@monmail.fr);
$this->doctrine->em->persist($user);
$this->doctrine->em->save();

 

Sur cet même exemple, on peut récupérer un User par son id (ici id = 15) et afficher son pseudo :

$user = $this->doctrine->em->find('Entities\User', 15);
echo $user->getNickname();

 

Si vous voulez crééer vos propres méthodes pour une table, il vous suffit de modifier le models présent dans application/modles/Entities

 

Pour le reste, je vous laisse consulter la documentation Doctrine très complète

 

J'espère que ce tuto vous sera utile, n'hésitez pas si vous n'arrivez pas à installer / configurer ou si vous avez des questions !

 

Commentaires


Poster un commentaire


Partenaires : Mon-Message.fr