我知道这是一个古老的问题,但这总是困扰着我。我不知道ZF 2是否做了什么来解决它(我还没有机会玩它),但我写了一个插件加载器插件来处理这个ZF 1!
问题是,即使在设置模块自动加载器并将插件保存在模块的插件文件夹中时,它也只会设置自动加载(无论如何都是交叉模块),而不是注册。这意味着你可以在你的application.ini行实例化的插件,但它会自动载入,并为每个模块注册。
无论如何,这里有一个可能的解决方案来确保模块插件仅注册到活动模块。或者,您可以循环访问模块插件目录中的所有文件,而不是提供类映射,但这会感觉很难受,并且可能很慢。
<?php
class BaseTen_Controller_Plugin_ModulePluginLoader extends Zend_Controller_Plugin_Abstract {
private $_pluginMap;
public function __construct(array $pluginMap) {
$this->_pluginMap = $pluginMap;
}
public function routeShutdown(Zend_Controller_Request_Abstract $request) {
$module = $request->getModuleName();
if(isset($this->_pluginMap[$module])) {
$front = Zend_Controller_Front::getInstance();
foreach($this->_pluginMap[$module] as $plugin) {
$front->registerPlugin(new $plugin());
}
}
}
}
因为我们需要一个类映射传递给构造函数,我们需要显式实例化,并与一的application.ini在线注册这个插件和前端控制器,而不是:
public function _initPluginLoader() {
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new BaseTen_Controller_Plugin_ModulePluginLoader(array(
'default' => array(
'Plugin_Foo',
'Plugin_Bar',
...
),
'foo' => array(
'Foo_Plugin_Foo',
'Foo_Plugin_Bar',
...
)
)));
}
最早插件可以运行在routeShutdown
,否则我们不会知道活动模块。这意味着,使用这种方法注册的其他插件只能从dispatchLoopStartup
开始运行。大多数情况下,我们可能对preDispatch
和postDispatch
挂钩感兴趣,但值得注意。