如何使用模块加载插件

时间:2010-09-08 17:55:00

标签: zend-framework plugins load bootstrapping

我在 admin 模块目录的plugins目录中有此插件。所以,它在application/modules/admin/plugins/LayoutPlugin.php

<?php
class LayoutPlugin extends Zend_Controller_Plugin_Abstract
{
   public function preDispatch(Zend_Controller_Request_Abstract $request)
   {
      $layout = Zend_Layout::getMvcInstance();
      $view = $layout->getView();

      $view->whatever = 'foo';
   }
}

我想用它将变量发送到布局视图。每当我在 admin 引导程序中尝试Fatal error: Class 'LayoutPlugin' not found时,我都会得到Zend_Controller_Front::getInstance()->registerPlugin(new LayoutPlugin());

如何在模块中加载插件?

2 个答案:

答案 0 :(得分:1)

模块bootstraps默认设置模块自动加载器,所以如果你将类重命名为Admin_Plugin_LayoutPlugin,ZF应该能够找到它。

请记住,无论您是否在管理模块中,管理引导程序(如所有引导程序)都将运行,因此如果您打算为管理页面分配一些额外的变量,则需要在注册插件之前确保admin是当前模块。

答案 1 :(得分:1)

我知道这是一个古老的问题,但这总是让我烦恼的事情。我不知道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());
            }
        }
    }
}

因为我们需要将classMap传递给构造函数,所以我们需要明确地实例化并使用Front Controller注册此插件,而不是在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开始运行。大多数情况下,我们可能对preDispatchpostDispatch钩子感兴趣,但值得记住。