zend-framework2 - Zend Framework 2 - 应用程序/模块/服务管理器 - Oh My

标签 zend-framework2 zend-db zend-log

作为一名长期的 Zend Framework 1 开发人员,我刚刚开始学习 Zend Framework 2。我在理解新术语时遇到了一些麻烦。

回到 ZF1,如果我想创建一个对应用程序来说是全局的记录器,我会将配置添加到 application.ini 文件中,并且 Bootstrap 会将其初始化为资源(我希望我说的是对的)。因此,我可以从我的任何模块 Controller 通过引导资源访问记录器。

进入 ZF2,模块有点不同,它们是独立的,但我对它们如何与应用程序交互有点困惑。在我看来,这就是 ServiceManager 发挥作用的地方。我的目标是让我的模块(不是 Controller ,而是模块本身)检查应用程序是否定义了一个记录器,如果有,则在整个模块中使用该记录器。如果应用程序没有定义记录器,我希望模块为模块范围的日志记录定义记录器。

这个问题也与数据库有关,假设我想让应用程序定义数据库连接的逻辑,而我希望模块定义它所需的表的逻辑。我该如何配置它,以及如何/在哪里判断应用程序中是否已经定义了数据库资源。

注意:我已经浏览了 Rob Allen 的快速入门(相当多的信息,也是迄今为止我发现的唯一没有晦涩难懂的资源)和 ZF2(阅读文档),并且已经用谷歌搜索了很多。我发现,当涉及到拼图的某些部分“去哪里”时,信息通常非常模糊。

最佳答案

您从 Zend Framework 1.x 了解到的是“应用程序资源”。

“应用程序资源”的概念在 Zend Framework 2 中被所谓的 "services" 取代。 (简介here)

另一个变化是模块本身。在 ZF1 中,模块主要是处理某些请求的应用程序的子部分。这在 ZF2 中不再适用:如果您的模块定义了一个服务或 Controller ,那么现在所有应用程序都可以访问该服务或 Controller 。有一个很好的介绍 differences between ZF1 and ZF2 by Gary Hockin .

但无论如何,模块不是独立的。它们应该在隔离的环境中开发,并且依赖尽可能少,但它们提供了影响所有应用程序的交叉关注功能。

对于您的记录器的具体情况,我建议您的模块始终定义一个记录器并使用它。有条件地定义记录器的方法如下:

class MyModule
{
    public function onBootstrap($e)
    {
        // $e->getTarget() is the \Zend\Mvc\Application
        $sm = $e->getTarget()->getServiceManager();

        if (!$sm->has('some-logger-name')) {
            $sm->setFactory('some-logger-name', function ($sl) {
                return new MyLogger($sl->get('some-db'));
            });
        }
    }
}

然后,您就可以在所有应用程序中使用您的“一些记录器名称”。

另一种方法是只定义记录器服务并让其他模块或配置稍后覆盖它:
class MyModule
{
    public function getConfig()
    {
        return array(
            'service_manager' => array(
                'factories' => array(
                    'some-logger-name' => 'My\Logger\Factory\ClassName'
                ),
            ),
        );
    }
}
getServiceConfig 也是如此。 ,灵 active 较差,无法缓存,但优先级高于 getConfig (允许覆盖)并允许您将服务工厂定义为闭包:
class MyModule
{
    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'some-logger-name' => function ($sl) {
                    return new MyLogger($sl->get('some-db'));
                },
            ),
        );
    }
}

然后,您甚至可以定义一个必须用于决定使用哪个记录器(服务名称)的配置键。

模块和配置的概念是“最后一个模块获胜”,因此您可以定义服务 'some-logger-name'在您的模块中或在它之前加载的任何模块中。

相同的概念也适用于您的数据库连接。

如您所见,转向服务已经为您提供了一定程度的自由。

请记住,并不是“应用程序”为您定义了一些东西:模块定义了您的服务/配置/事件等……正在运行的应用程序是所有这些东西的组合。

关于zend-framework2 - Zend Framework 2 - 应用程序/模块/服务管理器 - Oh My,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14882469/

相关文章:

doctrine-orm - 如何从 Doctrine 中的部分实体获取外键?

viewmodel - ZF2 : How to propagate Controller return to layout template?

php - 包含日期的复杂查询

php - Zend Framework 默认日志级别

zend-framework2 - 在ZF2中停用 View

zend-framework2 - 如何将语言变量传递给ZF2中的布局?

zend-framework - 使用 Zend_DB_Table 选择查询

zend-framework - Zend_Validate_Db_RecordExists 与 Doctrine 2?

php - ZF2 应用程序范围的 var(自定义唯一请求 id)