我真的很困惑什么时候使用 getServiceLocator 什么时候不使用。 例如:
+ Module
-+ Helloworld
--+ src
---+ Controller
----+ IndexController.php
----+ IndexControllerFactory.php
---+ Service
----+ LogginService.php
----+ GreetingService.php
----+ GreetingServiceFactory.php
GreetingServiceFactory.php 包含以下内容:
<?php
namespace Helloworld\Service;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class GreetingServiceFactory implements FactoryInterface
{
public function createService (ServiceLocatorInterface $serviceLocator)
{
$greetingService = new GreetingService();
$greetingService->setEventManager($serviceLocator->get('eventManager'));
$loggingService = $serviceLocator->get('loggingService');
$greetingService->getEventManager()->attach('getGreeting', array(
$loggingService,
'onGetGreeting'
));
return $greetingService;
}
}
IndexControllerFactory.php 的内容是:
<?php
namespace Helloworld\Controller;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class IndexControllerFactory implements FactoryInterface
{
public function createService (ServiceLocatorInterface $serviceLocator)
{
$ctr = new IndexController();
$ctr->setGreetingService($serviceLocator->getServiceLocator()
->get('greetingService'));
return $ctr;
}
}
如您所见,我的 ControllerFactory 中需要 $serviceLocator->getServiceLocator(),但 ServiceFactory 中不需要。为什么?两者都使用相同的接口(interface) ServiceLocatorInterface,它甚至没有定义 getServiceLocator() 方法。
模块.config.php:
'controllers' => array(
'factories' => array(
'Helloworld\Controller\Index' => 'Helloworld\Controller\IndexControllerFactory'
)
)
,
'service_manager' => array(
'invokables' => array(
'loggingService' => 'Helloworld\Service\LoggingService'
),
'factories' => array(
'greetingService'=> 'Helloworld\Service\GreetingServiceFactory'
),
)
如有任何澄清,我将不胜感激:)
祝你有美好的一天!
最佳答案
getServiceLocator
方法定义在 AbstractPluginManager
上, 因为它实现了 ServiceLocatorAwareInterface
.正如 Maks3w 指出的那样,它不是 ServiceLocatorInterface
的一部分。 ,因此在实现服务工厂时避免使用它。
你无论如何都可以将你的工厂定义为闭包并仍然使用它:
class MyModule
{
public function getControllerConfig()
{
return array(
'factories' => array(
'IndexController' => function (
\Zend\ServiceManager\AbstractPluginManager $pm
) {
$ctr = new IndexController();
$ctr->setGreetingService(
$pm
->getServiceLocator()
->get('greetingService')
);
return $ctr;
},
),
);
}
}
虽然在此示例中 $pm
确实是一个 ServiceLocatorInterface
实例,但您仍然需要获取对“主”服务管理器的引用才能访问 '问候服务'
。
ZF2 对 Controller 、服务、 View 助手、 Controller 插件等使用不同的服务管理器或插件管理器...这主要是为了类型提示(查看 AbstractPluginManager
的接口(interface)以了解如何实现类型严格性)和安全性。
在这种情况下,安全问题是不允许访问不是 Controller 的服务,尤其是带有动态 controller
参数的路由。这就是 Controller 保存在单独的插件管理器中的原因。
由于 Controller 插件管理器是从“主”服务管理器创建的,因此它也通过 ServiceLocatorAwareInterface
进行了初始化。
为了更清楚地说明这一点,我添加了一个关系图(不包括工厂并且不要将其视为有效的 UML):
关于php - ZF2 何时使用 getServiceLocator() 何时不使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14911965/