邮件列表和推特上的许多人最近询问如何使用ZendFramework的自动加载器自动加载Doctrine,以及如何自动加载您创建的Doctrine模型。最近用Doctrine做了几个项目,其实可以给出答案。
简短的回答:只需将它附加到Zend_Loader_Autoloader
。
现在了解详情。
首先,确保Doctrine.php
文件的路径在您的include_path
上。
接下来,Zend_Loader_Autoloader
允许您指定它可以自动加载的“名称空间”(不是实际的PHP名称空间,更像是类前缀),对于它将自动加载的类,以及您附加到它的自动加载回调.通常,您在这样做时包括尾随下划线:
$autoloader = Zend_Loader_Autoloader::getInstance(); $autoloader->registerNamespace('Foo_'); $autoloader->pushAutoloader($callback, 'Bar_');
但是,因为Doctrine有一个用于处理常见操作的主类,“Doctrine”,我们必须省略尾部的下划线,以便Doctrine
类本身可以被自动加载。我们需要做两个不同的操作:首先,为Doctrine添加一个命名空间到Zend_Loader_Autoloader
(这将允许我们自动加载Doctrine类本身,以及各种Doctrine子组件类),然后注册Doctrine自动加载器(这将被Doctrine用来加载表类、监听器等项目):
$autoloader->registerNamespace('Doctrine') ->pushAutoloader(array('Doctrine', 'autoload'), 'Doctrine');
这会处理Doctrine自动加载器;现在,让我们转向Doctrine模型。
首先,告诉Doctrine你想要自动加载。您可以通过告诉它使用“保守”模型加载(延迟加载或自动加载的简写)和自动加载表类来做到这一点:
$manager = Doctrine_Manager::getInstance(); $manager->setAttribute( Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE ); $manager->setAttribute( Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true );
从这里开始,您需要确保您确实可以自动加载模型。通常,您告诉Doctrine在哪里可以找到模型,但我们在ZendFramework应用程序中,所以让我们利用ZF约定。
我通常将我的模型代码与我的应用程序代码放在一起:
application |-- Bootstrap.php |-- configs |-- controllers |-- models <- HERE |-- modules | `-- blog | |-- Bootstrap.php | |-- controllers | |-- forms | |-- models <- HERE | |-- services | `-- views `-- views
ZendFramework已经通过Zend_Loader_Autoloader_Resource
和Zend_Application_Module_Autoloader
提供了自动加载应用程序资源的机制。假设您已经在模块引导程序中扩展了Zend_Application_Module_Bootstrap
,那么您基本上已经设置好了。诀窍与您的表类有关;您的表类必须与您的模型放在同一目录中,并且它们必须的名称与您的模型完全相同,并带有后缀“Table”。
例如,如果您在文件application/modules/blog/models/Entry.php
中有类Blog_Model_Entry
扩展Doctrine_Record
,相关的表类将是文件application/modules/blog/models/EntryTable.php
中的Blog_Model_EntryTable
。
我通过我的Bootstrap
类自动执行大部分设置,通常如下所示:
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; } }
在您的配置中,您需要添加两个键:一个用于使用默认自动加载器注册Doctrine命名空间,另一个用于dsn:
autoloaderNamespaces[] = "Doctrine" dsn = "DSN to use with Doctrine goes here"
我还有一个脚本,可用于一次加载所有模型类,以便执行生成模式或测试交互等操作。稍后我会在博客中介绍这些内容。希望以上信息能对尝试集成这两个代码库的一两个人有所帮助!
更新
- 2009-08-21:添加了有关使用默认自动加载器注册Doctrine命名空间的信息