Integrating CodeIgniter and Doctrine

Posted on 12/28/09, in CodeIgniter, by kevin

Having used CodeIgniter over the past year or so, I came to realise some limitations with the Database library. CodeIgniter does not have a proper ORM library like a lot of other frameworks provide. With an ORM library, you have a lot more tools at your disposal to not only increase productivity but also improve database transaction efficiency.

Doctrine is a full blown PHP ORM framework that can be integrated into other frameworks or old school PHP applications. Here is how to integrate the framework to CodeIgniter.

Download a copy of the Doctrine framework and place it somewhere in your web directory (for this tutorial I am placing it at the web root directory /). My directory structure looks like;

.
..
.htaccess
index.php
licence.txt
user_guide
system
doctrine
application

Set database credentials

As you would with any other CI app that utilises a database, enter the connection details in the database.php file inside of the config folder.

//.. application/config/database.php
$db['default']['hostname'] = "[hostname]";
$db['default']['username'] = "[username]";
$db['default']['password'] = "[password]";
$db['default']['database'] = "[databasename]";
$db['default']['dbdriver'] = "[driver e.g. mysql]";
$db['default']['dbprefix'] = "";
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = "";
$db['default']['char_set'] = "utf8";
$db['default']['dbcollat'] = "utf8_general_ci";

Enable hooks

In the config file [application/config/config.php] enable hooks by setting hooks to TRUE.

//.. application/config/config.php
$config['enable_hooks'] = TRUE;

Insert the hook

Create a new file in the hooks directory [application/hooks] called doctrine.php

//.. application/hooks/doctrine.php
if(!defined('BASEPATH')) exit('file locked');

require_once( FCPATH . 'doctrine/lib/Doctrine.php' );

class DoctrineHook
{

	function bootstrap_doctrine()
	{
		require_once( APPPATH . '/config/database.php' );

		spl_autoload_register(array('Doctrine', 'autoload'));
		Doctrine_Manager::getInstance()->setAttribute('model_loading', 'aggressive');

		if (!isset($db[$active_group]['dsn'])) {
			$db[$active_group]['dsn'] = $db[$active_group]['dbdriver'] .
							'://' . $db[$active_group]['username'] .
							':' . $db[$active_group]['password'].
							'@' . $db[$active_group]['hostname'] .
							'/' . $db[$active_group]['database'];
		}

		Doctrine_Manager::connection($db[$active_group]['dsn']);
		Doctrine_Manager::setAttribute(Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE, true);
		Doctrine_Manager::setAttribute(Doctrine_Core::ATTR_USE_NATIVE_ENUM, true);
		Doctrine::loadModels(APPPATH . DIRECTORY_SEPARATOR . 'models/doctrine/');
	}

}

Register the hook

So, now we have the hook in place we need to tell CI to execute the hook on system start up. Over to application/config/hooks.php…

//.. application/config/hooks.php
 if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
| -------------------------------------------------------------------------
| Hooks
| -------------------------------------------------------------------------
| This file lets you define "hooks" to extend CI without hacking the core
| files.  Please see the user guide for info:
|
|	http://codeigniter.com/user_guide/general/hooks.html
|
*/
$hook['pre_controller'][] = array(
	'class' => 'DoctrineHook',
	'function' => 'bootstrap_doctrine',
	'filename' => 'doctrine.php',
	'filepath' => 'hooks'
	);

/* End of file hooks.php */
/* Location: ./system/application/config/hooks.php */

With this now in place, CI will load doctrine upon each load. There is one thing left to do. Some of you may have noticed in the doctrine.php hook we created, we told Doctrine to load our models from application/models/doctrine. I created the doctrine folder inside the models folder to purposely seperate doctrine classes from my CI models.

Everything should now work and you can call a model using native PHP class loading methods…

//.. inside a controller we may call a user class like this;
$user = new User();
Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogosphere News
  • DZone
  • email
  • LinkedIn
  • MySpace
  • PDF
  • RSS
  • StumbleUpon
  • Twitter