ZF2 - 使记录器全局可访问,理想情况下延迟加载或事件

时间:2016-06-09 14:12:28

标签: php logging zend-framework2

我的module_config中定义了各种Logger。需要特定记录器的每个控制器或服务都需要通过其工厂注入记录器。

理想情况下,我不想担心这种注射,并且可以使记录器可以访问(没有我的服务/控制器中的服务定位器)。只有当我需要它们时,它们应该是懒惰加载/实例化的。

有没有办法这样做?我在考虑初始化,处理或使用事件管理器。

我知道,这听起来像回到了服务定位器。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我想最干净的方法是使用controller plugin从控制器调用记录器。

实施非常简单:

创建一个新的PHP类并使其扩展Zend\Mvc\Controller\Plugin\AbstractPlugin。 它的构造函数应该接受logger作为依赖,并且它的__invoke方法可以用来“神奇地”检索记录器。

接下来,为它创建一个工厂,实现Zend\ServiceManager\FactoryInterface并使用它来注入依赖项(即记录器)

在servicemanager配置中注册工厂:

'controller_plugins' => array( 'factories' => array( 'Logger' => 'MyApp\Controller\Plugin\Logger', ) ),

然后您可以在控制器中调用它,如下所示:

$this->logger();

(有关创建自定义控制器插件的详细信息,请参阅http://lab.empirio.no/custom-controller-plugin-in-zf2.html)。

延迟加载记录器可以通过在lazy_services配置的service_manager密钥下注册为延迟服务来处理。

对于您的服务,您可以实现自己的ServiceLocator版本(也称为插件管理器)。 它会像ViewHelperManagerControllerPluginManagerValidatorPluginManager等一样工作。

我不会解释如何做到这一点,因为它有很多代码,网上有很多关于如何创建代码的方法。

修改 正如下面提到的@tasmaniski你可以使用基于标记接口的注入使用初始化器(ZF2在内部通过'Aware'接口使用它)。 请注意,初始化程序相对较慢,尤其是在使用不当时,即作为Module.php或module.config.php文件中的闭包。

此外,初始化程序会被ServiceManager的{​​{1}} mtehod提取的每个服务调用,因此会增加很多开销。 然而,这是一个比编写自己的插件管理器实现更容易,更快速的解决方案。

答案 1 :(得分:0)

我在我的应用程序/架构中有完全相同的问题。 所以解决方案是:

在Controllers的范围内,正如@FuST所说,你必须创建控制器插件。比所有控制器都可以使用记录器。

在服务范围内,我可以进行"接口注入"。 因此,在您的服务中,您必须添加3件事:

// #1 Create interface with setLogger($logger); method
class YourService implement LoggerInterface { 
    private $logger; // #2 Define private $logger;

    // #3 Add method that you will use to  inject the $logger later
    public function setLogger($logger){
        $this->logger = $logger;
    }
}

创建初始化程序并在每个实现 LoggerInterface 的类中注入$ logger。