Php ZF2 Zend注册表的替代方案
我刚刚开始使用ZF2,我真的很喜欢它 有一件事让我有点困惑,那就是缺少注册表组件。我意识到,在大多数情况下,服务经理会使注册表过时。我非常依赖它和它的伟大 但有时我发现自己需要访问“全局”对象,而我没有访问服务管理器的权限。例如,在我的域\用户对象中,我需要访问Zend\日志 我不想让服务管理器在我的域对象中可用,因为它们美丽而原始,而且不受这些考虑的影响。我可以在需要时“新建”一个日志实例,但我经常这样做,我宁愿手头有一个预配置的实例。我可以用单件包装,但这似乎是一个倒退。我可以创建自己的迷你注册表,但如果这是一个好主意,我相信Zend的人会留下这样一个组件 那么,还有什么其他选择呢 编辑:Php ZF2 Zend注册表的替代方案,php,zend-framework,dependencies,zend-framework2,registry,Php,Zend Framework,Dependencies,Zend Framework2,Registry,我刚刚开始使用ZF2,我真的很喜欢它 有一件事让我有点困惑,那就是缺少注册表组件。我意识到,在大多数情况下,服务经理会使注册表过时。我非常依赖它和它的伟大 但有时我发现自己需要访问“全局”对象,而我没有访问服务管理器的权限。例如,在我的域\用户对象中,我需要访问Zend\日志 我不想让服务管理器在我的域对象中可用,因为它们美丽而原始,而且不受这些考虑的影响。我可以在需要时“新建”一个日志实例,但我经常这样做,我宁愿手头有一个预配置的实例。我可以用单件包装,但这似乎是一个倒退。我可以创建自己的迷你
那么,我可以用Zend DI吗?我看到这个问题部分地涵盖了它,您正是在解决依赖注入的问题。我以前写过关于这个主题的博客,如果你喜欢一个日志记录者,该如何做 其思想是注入预配置的记录器。创建域\用户对象时,将插入记录器。这使得域\用户对象仅依赖于记录器,而不知道如何创建记录器。如果您依赖于记录器接口,则更好,因此您可以切换到任何您想要的记录器实现 示例 例如,我假设您使用的是Zend\Log。您有一个类似于
Zend\Log\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,您应该与工厂合作,将此记录器注入到您的对象中。最好的方法是首先将记录器定义为服务,因为您也可以将记录器重新用于其他对象
注意:我在这里使用服务管理器,而不是Zend\Di。Zend\Di已经过时,取而代之的是更快、更灵活的Zend\ServiceManager。两者都可以实现依赖注入
适用于您的工厂:
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;
}
}
然后注册此工厂,为您创建服务“记录器”。在module.config.php中:
'service_manager' => array(
'factories' => array(
'logger' => 'MyModule\Factory\LoggerFactory',
),
),
现在,您的服务经理中提供了记录器
。对于您的域模型,请执行相同的操作。首先创建工厂:
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',
),
),
如果您有权访问服务定位器,则可以获取域\用户并自动注入记录器:
$user = $sl->get('Domain\User');
“正确”的方法是将日志对象作为依赖项传递到域\用户对象中。不过,在域模型中,日志记录并不是你通常会做的事情——你能再解释一下为什么需要它吗?嗨,蒂姆,我用它只是为了获取变量的变量转储或打印。只是为了调试,真的。你的编辑听起来不错-Zend\Di\Di似乎是在对象构造时激发依赖关系的一个不错的选择。但是,正如您所提到的,只有当它根本不是一个真正的依赖项(如日志记录)时,才应该这样做。为什么不在服务管理器中将其注册为服务呢?将“日志记录功能”从您美丽而原始的域实体中移开怎么样?