Integrating Doctrine 2 with CodeIgniter 2

An easy to follow tutorial for integrating Doctrine 2 with CodeIgniter 2 is available at doctrine-project. Unfortunately, there are a few configuration problems which would prevent the proper loading of proxies if that configuration were to be used exactly as it is.

The problem is related to how the Proxies ClassLoader has been registered. PHP will attempt to load proxies which have the namespace Proxies from the directory {APPATH}/models/proxies/Proxies.

$proxiesClassLoader = new ClassLoader('Proxies', APPPATH.'models/proxies');
$proxiesClassLoader->register();

However, Doctrine has been configured to write proxies to the directory {APPATH}/models/proxies.

$config->setProxyDir(APPPATH.'/models/proxies');
$config->setProxyNamespace('Proxies');

Additionally, the suggested configuration registers a DefaultAnnotationDriver using the directory {APPPATH}/models/Entities which is unlikely to exist.

$driverImpl = $config->newDefaultAnnotationDriver(array(APPPATH.'models/Entities'));
$config->setMetadataDriverImpl($driverImpl);

The configuration and instructions shown below address these issues and contain some other useful notes on the integration.

Setting up the File Structure

Note: a screenshot is available to demonstrate the file structure.

  1. Add a php file to your application/libraries folder called Doctrine.php.
  2. Copy the content of the configuration file below and save it to your Doctrine.php file.
  3. Put the Doctrine folder inside that same libraries folder.
  4. Create a folder called proxies in your application/models folder.
  5. (Optional) Edit your config/autoload.php file and add doctrine to your $autoload[‘libraries’].

Creating your Doctrine CodeIgniter Library

<?php
use Doctrine\Common\ClassLoader,
    Doctrine\ORM\Configuration,
    Doctrine\ORM\EntityManager,
    Doctrine\Common\Cache\ArrayCache,
    Doctrine\DBAL\Logging\EchoSQLLogger;

class Doctrine {

  public $em = null;

  public function __construct()
  {
    // load database configuration from CodeIgniter
    require_once APPPATH.'config/database.php';

    // Set up class loading. You could use different autoloaders, provided by
    // your favorite framework, if you want to.
    require_once APPPATH.'libraries/Doctrine/Common/ClassLoader.php';

    $doctrineClassLoader = new ClassLoader('Doctrine',  APPPATH.'libraries');
    $doctrineClassLoader->register();
    $entitiesClassLoader = new ClassLoader('models', APPPATH);
    $entitiesClassLoader->register();
    $proxiesClassLoader = new ClassLoader('proxies', APPPATH.'models');
    $proxiesClassLoader->register();

    // Set up caches
    $config = new Configuration;
    $cache = new ArrayCache;
    $config->setMetadataCacheImpl($cache);
    $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver(
		array(APPPATH.'models')));
    $config->setQueryCacheImpl($cache);

    // Proxy configuration
    $config->setProxyDir(APPPATH.'models/proxies');
    $config->setProxyNamespace('proxies');

    // Set up logger
//    $logger = new EchoSQLLogger;
//    $config->setSQLLogger($logger);

    $config->setAutoGenerateProxyClasses( TRUE );

    // 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 EntityManager
    $this->em = EntityManager::create($connectionOptions, $config);
  }
}

Usage

Assuming that Doctrine has been autoloaded (step 5 above), you may use the EntityManager from your CodeIgniter controllers like so:

/* @var $em Doctrine\ORM\EntityManager */
$em = $this->doctrine->em;
Share

Leave a Reply

Your email will not be published. Name and Email fields are required.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>