2

我需要在任何MvcEvent::EVENT_BOOTSTRAP侦听器执行之前执行一些代码。显然Module::onBootstrap是没有选择的。我以以下代码结束:

class Module
{

    function init(\Zend\ModuleManager\ModuleManager $moduleManager)
    {
        $moduleManager->getEventManager()->attach(
                MvcEvent::EVENT_BOOTSTRAP, array(ClassX, 'StaticMethodOfClassX'), 20000);
    }

}

我不想对array(ClassX, 'StaticMethodOfClassX')引用进行硬编码,而是从服务管理器那里获取。我的问题是我不知道如何在模块的 init 方法中获取服务管理器引用。有什么帮助吗?或者这在 ZF2 现在是不可能的?无论这种模式或意见的任何变体都将受到赞赏;)

编辑:

我将澄清“显然 Module::onBootstrap 不是一个选项”,因为可能不是那么微不足道;)

Module::onBootstrap触发事件时会执行模块方法MvcEvent::EVENT_BOOTSTRAP,但每个模块的Module::onBootstrap方法与该事件的关联取决于加载模块的顺序。由于,特定Module::onBootstrap方法的执行顺序取决于存在哪些其他模块以及其他模块如何影响该特定模块的加载顺序。此外,任何附加到MvcEvent::EVENT_BOOTSTRAP优先级大于 1 的事件的侦听器都将在任何模块Module::onBootstrap方法之前执行,例如 ViewManager::onBootstrap侦听器。所以,要实现我想要的

我需要在任何 MvcEvent::EVENT_BOOTSTRAP侦听器执行之前执行一些代码

模块 obBootstrap 方法不是一个选项。

4

5 回答 5

6

这是一个非常古老的帖子,但由于没有接受任何答案,而且我最近需要实现同样的目标,我想我会分享我的解决方案。

我需要在触发 Bootstrap 事件之前访问 ServiceManager 的原因是,我可以使用从数据库中检索到的值来操作合并的配置。

问题

Zend文档中的示例显示了如何操作合并的配置,但在特定时间服务管理器是空的,因此无法检索数据库适配器等内容。

解决方案

在您的模块类中,实现接口InitProviderInterface并添加适当的方法。

public function init(ModuleManagerInterface $moduleManager)
{
    $eventManager = $moduleManager->getEventManager();
    $eventManager->attach(ModuleEvent::EVENT_LOAD_MODULES_POST, [$this, 'onLoadModulesPost']);
}

EVENT_LOAD_MODULES_POST事件将在 EVENT_MERGE_CONFIG 事件之后但在EVENT_BOOTSTRAP事件触发之前被调用。同样在这个特定时间,ServiceManager 将包含您想要访问的所有工厂、可调用类。

您的回调方法可能看起来像。

public function onLoadModulesPost(ModuleEvent $event)
{
    /* @var $serviceManager \Zend\ServiceManager\ServiceManager */
    $serviceManager = $event->getParam('ServiceManager');
    $configListener = $event->getConfigListener();
    $configuration = $configListener->getMergedConfig(false);

    $someService = $serviceManager->get('Your/Custom/Service');
    $information = $someService->fetchSomeInformation();
    $configuration = array_merge($configuration, $information);

    $configListener->setMergedConfig($configuration);
    $event->setConfigListener($configListener);
    $serviceManager->setAllowOverride(true);
    $serviceManager->setService('Config', $configuration);
    $serviceManager->setAllowOverride(false);
}
于 2015-12-21T03:49:25.903 回答
0

你可以从 MvcEvent 中得到它

$locator = $event->getTarget()->getServiceLocator()->get('YourObject')

如果您无权访问该事件,则可以在引导程序上将该事件设置为 Module 类的属性,然后随时在您的 init 方法中使用它。

 public function onBootstrap($event) {
        $this->setMvcEvent($event);
 }

function init(\Zend\ModuleManager\ModuleManager $moduleManager)
{
    $locator = $this->mvc_event->getTarget()->getServiceLocator()->get('YourClass');
    $moduleManager->getEventManager()->attach(
            MvcEvent::EVENT_BOOTSTRAP, array(ClassX, 'StaticMethodOfClassX'), 20000);
}
于 2013-10-22T21:37:28.007 回答
0

也许稍后一点,但希望它会帮助别人。在初始化点,服务管理器中没有太多服务,但您可以访问它:

public function init(ModuleManager $moduleManager)
{
    $sm = $moduleManager->getEvent()->getParam('ServiceManager');
    $applicationConfig = $sm->get('applicationconfig');
    var_dump($applicationConfig['modules']);
}

在这种情况下,我们正在检索模块名称。

于 2015-01-21T10:45:54.980 回答
0

你在你的应用程序中使用ZfcBase吗?AbstractModule 有一个 boostrap 方法(不是onBootstrap),它由这个事件处理程序在 init 方法中执行

$sharedManager->attach('Zend\Mvc\Application', 'bootstrap', function($e) use ($instance, $moduleManager) {
    $app = $e->getParam('application');
    ...
    $instance->bootstrap($moduleManager, $app);
});

当然,您可以在没有 ZfcBase 的情况下使用这种方法。

然后你可以实现Zend\ServiceManager\ServiceLocatorAwareInterface

public function bootstrap(\Zend\ModuleManager\ModuleManager $moduleManager, \Zend\Mvc\ApplicationInterface $app){
    $this->setServiceLocator($app->getServiceManager());
    parent::bootstrap($moduleManager, $app);
}

public function setServiceLocator(\Zend\ServiceManager\ServiceLocatorInterface $serviceLocator){
    $this->_serviceLocator = $serviceLocator;
    return $this;
}

public function getServiceLocator(){
    return $this->_serviceLocator;
}
于 2014-03-20T18:54:53.173 回答
-1

这是更好的主意。

类模块

public function onBootstrap(MvcEvent $e)
{

    $sm = $app->getServiceManager();
    $config = $sm->get('config');

这就是全部。

于 2015-02-28T09:31:01.480 回答