php - ZF2 Zend Registry 的替代品

标签 php zend-framework dependencies zend-framework2 registry

我刚开始使用 ZF2 并且非常喜欢它。

让我有点困惑的一件事是缺少注册表组件。我意识到服务管理器在大多数情况下使注册表过时了。我非常依赖它,它很棒。

但有时我发现自己需要访问“全局”对象,但我无权访问服务管理器。例如,在我的 Domain\User 对象中,我需要访问 Zend\Log。

我不想让服务管理器在我的域对象中可用,因为它们既美观又原始,并且不受此类考虑因素的影响。我可以在需要时“新建”一个日志实例,但我经常这样做,所以我宁愿手头有一个预配置的实例。我可以将它包装在一个单例中,但这似乎是一种倒退。我可以创建自己的迷你注册表,但如果这是个好主意,我相信 Zend 人员会保留这样一个组件。

那么,还有哪些其他选择呢?

编辑:

那么,我可以使用 Zend DI 吗?我看到这个问题部分涵盖了它,Configuring class alias for using with Zend\Di\Di

最佳答案

您正是在解决依赖注入(inject)问题。我以前写过关于这个话题的博客,如何refactor towards dependency injection如果你有soft dependencies怎么办?就像一个记录器。

这个想法是你注入(inject)预配置的记录器。创建域\用户对象时,将注入(inject)记录器。这使得 Domain\User 对象只依赖于记录器而不知道如何创建记录器。如果您依赖 Logger 接口(interface),那就更好了,这样您就可以切换到您想要的任何记录器实现。

示例

例如,我假设您正在使用 Zend\Log。您有一个像 Zend\Log\Logger 这样的 Logger,并附有各种编写器。记录器实现了 Zend\Log\LoggerInterface

您的域\用户类:

namespace Domain;

Zend\Log\LoggerInterface;

class User
{
    protected $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function doSomething()
    {
        $this->logger->info('Do Something');

        //
    }
}

对于 Zend Framework,您应该使用工厂将此记录器注入(inject)到您的对象中。最好的方法是首先将记录器定义为服务,因为您也可以将记录器重用于其他对象。

注意我在这里使用服务管理器而不是 Zend\Di。 Zend\Di 已过时,取而代之的是更快、更灵活的 Zend\ServiceManager。两者都可以实现依赖注入(inject)。

记录器的工厂:

namespace MyModule\Factory;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

use Zend\Log\Logger;

class LoggerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $logger = new Logger;
        // do more with $logger here

        return $logger;
    }
}

然后注册这个工厂来为你创建服务“logger”。在你的 module.config.php 中:

'service_manager' => array(
    'factories' => array(
        'logger' => 'MyModule\Factory\LoggerFactory',
    ),
),

现在 logger 在您的服务管理器中可用。对于您的域模型,执行相同的操作。先创建工厂:

namespace MyModule\Factory;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

use Domain\User;

class UserFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $logger = $serviceLocator->get('logger');

        $user = new User($logger);
        return $user;
    }
}

然后也注册这个:

'service_manager' => array(
    'factories' => array(
        'logger' => 'MyModule\Factory\LoggerFactory',
        'Domain\User' => 'MyModule\Factory\UserFactory',
    ),
),

如果您有权访问服务定位器,您可以获得域\用户并自动注入(inject)记录器:

$user = $sl->get('Domain\User');

关于php - ZF2 Zend Registry 的替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20258964/

相关文章:

php - Nginx/PHP FPM 优雅停止 (SIGQUIT) : not so graceful

php - 在 PHP 中编辑 Access 数据库

php - 处理 PHP 中的应用程序级错误

php - Zend_Form 单选元素

php - Laravel 5.2 - srmklive/laravel-paypal 问题

zend-framework - 如何将 Zend 框架 2 集成到 Netbeans 7.2 IDE

php - zend 翻译和 smarty

module - 如何强制 npm 3 安装嵌套依赖项?

android - 找不到与给定名称匹配的资源(在 'dialogCornerRadius' 处,值为 '?android:attr/dialogCornerRadius' )

android - 关于一个应用程序中的多个模块(带 Activity 的库)