A number of people on the mailing list and twitter recently have asked how
to autoload Doctrine using Zend Framework's autoloader, as well as how to
autoload Doctrine models you've created. Having done a few projects using
Doctrine recently, I can actually give an answer.
The short answer: just attach it to Zend_Loader_Autoloader.
Now for the details.
First, make sure the path to the Doctrine.php file is on your
include_path.
Next, Zend_Loader_Autoloader allows you to specify "namespaces"
(not actual PHP namespaces, more like class prefixes) it can autoload, both
for classes it will autoload, as well as for autoload callbacks you attach
to it. Typically, you include the trailing underscore when doing so:
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('Foo_');
$autoloader->pushAutoloader($callback, 'Bar_');
However, because Doctrine has a master class for handling common operations,
"Doctrine", we have to omit the trailing underscore so that the
Doctrine class itself may be autoloaded. We need to do two
different operations: first, add a namespace to
Zend_Loader_Autoloader for Doctrine (which will allow us to
autoload the Doctrine class itself, as well as the various doctrine
subcomponent classes), and then register the
Doctrine autoloader (which will be used by Doctrine to load items such as
table classes, listeners, etc.):
$autoloader->
registerNamespace('Doctrine') ->
pushAutoloader(array('Doctrine',
'autoload'),
'Doctrine');
This takes care of the Doctrine autoloader; now, let's turn to Doctrine models.
First, tell Doctrine that you want to autoload. You do this by telling it to
use "conservative" model loading (shorthand for lazyloading or autoloading),
and to autoload table classes:
$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(
Doctrine::ATTR_MODEL_LOADING,
Doctrine::MODEL_LOADING_CONSERVATIVE
);
$manager->setAttribute(
Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES,
true
);
From here, you need to ensure you actually can autoload the models.
Normally, you tell Doctrine where to find models, but we're in a Zend
Framework application, so let's leverage ZF conventions.
I typically put my model code with my application code:
application
|-- Bootstrap.php
|-- configs
|-- controllers
|-- models <- HERE
|-- modules
| `-- blog
| |-- Bootstrap.php
| |-- controllers
| |-- forms
| |-- models <- HERE
| |-- services
| `-- views
`-- views
Zend Framework already provides mechanisms for autoloading application
resources via Zend_Loader_Autoloader_Resource and
Zend_Application_Module_Autoloader. Assuming you've extended
Zend_Application_Module_Bootstrap in your module bootstraps,
you're basically already set. The trick has to do with your table classes;
your table classes must be placed in the same directory as your
models, and they must be named exactly the same as your models,
with the suffix "Table".
For example, if you had the class Blog_Model_Entry extending
Doctrine_Record in the file
application/modules/blog/models/Entry.php, the related table
class would be Blog_Model_EntryTable in the file
application/modules/blog/models/EntryTable.php.
I automate most of this setup via my Bootstrap class, which
typically looks as follows:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{ protected
function _initAppAutoload
() { $autoloader =
new Zend_Application_Module_Autoloader
(array( 'namespace' =>
'App',
'basePath' =>
dirname(__FILE__),
));
return $autoloader;
} protected
function _initDoctrine
() { $this->
getApplication()->
getAutoloader() ->
pushAutoloader(array('Doctrine',
'autoload'));
$manager = Doctrine_Manager::
getInstance();
$manager->
setAttribute(Doctrine::
ATTR_AUTO_ACCESSOR_OVERRIDE,
true);
$manager->
setAttribute( Doctrine::
ATTR_MODEL_LOADING,
Doctrine::
MODEL_LOADING_CONSERVATIVE );
$manager->
setAttribute(Doctrine::
ATTR_AUTOLOAD_TABLE_CLASSES,
true);
$dsn =
$this->
getOption('dsn');
$conn = Doctrine_Manager::
connection($dsn,
'doctrine');
$conn->
setAttribute(Doctrine::
ATTR_USE_NATIVE_ENUM,
true);
return $conn;
}}
Within your configuration, you need to add two keys: one for registering the
Doctrine namespace with the default autoloader, and another for the dsn:
autoloaderNamespaces[] = "Doctrine"
dsn = "DSN to use with Doctrine goes here"
I also have a script that I use to load all model classes at once in order
to do things like generate the schema or test interactions. I'll blog about
those at a later date. Hopefully the above information will help one or two
of you out there trying to integrate these two codebases!
Updates
- 2009-08-21: added information about registering Doctrine
namespace with default autoloader
Yet another how-to for Zend Framework. You can find a lot of integration how-tos around the web with googling and I maybe the just one of them. I?m trying to find the wheel again. This one is like my subversion how-tos, a self reminder first. So let?s cut
Tracked: Dec 04, 08:10
Yet another how-to for Zend Framework. You can find a lot of integration how-tos around the web with googling and I maybe the just one of them. I?m trying to find the wheel again. This one is like my subversion how-tos, a self reminder first. So let?s cut
Tracked: Dec 05, 07:19
A couple of days ago I came home from one of the best PHP conferences in the world, Dutch PHP Conference 2009 with again a very elite list of speakers.Day 0: Tutorial DayThursday, June 11 was tutorial day. A whole day dedicated at learning new things by t
Tracked: Dec 21, 08:39
This Saturday user groups of the Netherlands (phpGG) and Belgium (PHPBelgium) organized Bughuntday at Best Western hotel "De Goderie" in Roosendaal (the Netherlands). Bughuntday is a whole day developers can come together to start fixing bugs for open-sou
Tracked: Dec 21, 09:50
If you're involved with PHP and you haven't heard of ZendCon before, you have been around the wrong croud!The past week was reserved for the biggest PHP event of the year bringing you the best of the best the open-source and commercial world have to offer
Tracked: Dec 21, 20:10
It's that time of year again where one looks back to all the things that have happened in the past 12 months. 2009 has to be the most thrilling, fastest ride ever and I'm really surprised to see it's nearly the end of this year.PHP
Tracked: Dec 29, 06:57
I’ve begun to investigate the Doctrine ORM library and how to integrate it into Zend Framework applications. I figure this post and any subsequent ones on the topic can grow into some sort of discovery series. So, my first post is going to be a s...
Tracked: Jan 12, 21:14