mac*_*ete 9 php frameworks service-locator zend-framework2
我真的很困惑何时使用getServiceLocator以及何时不使用.举个例子:
+ Module
-+ Helloworld
--+ src
---+ Controller
----+ IndexController.php
----+ IndexControllerFactory.php
---+ Service
----+ LogginService.php
----+ GreetingService.php
----+ GreetingServiceFactory.php
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
而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;
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我需要在我的ControllerFactory中使用$ serviceLocator-> getServiceLocator(),而不是在我的ServiceFactory中.为什么?两者都使用相同的接口ServiceLocatorInterface,它甚至没有定义getServiceLocator()方法.
module.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'
),
)
Run Code Online (Sandbox Code Playgroud)
我很感激任何澄清:)
祝你今天愉快!
Ocr*_*ius 20
该方法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;
},
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
虽然在此示例$pm中确实是一个ServiceLocatorInterface实例,但您仍需要获取对"主"服务管理器的引用才能访问'greetingService'.
ZF2为控制器,服务,视图助手,控制器插件等使用不同的服务管理器或插件管理器......主要用于类型提示(查看界面AbstractPluginManager以了解如何实现类型严格性)和安全性.
在这种情况下,安全问题是禁止访问非控制器的服务,尤其是对于具有动态controller参数的路由.这就是控制器保存在单独的插件管理器中的原因.
由于控制器插件管理器是从"主"服务管理器创建的,因此它也会被初始化ServiceLocatorAwareInterface.
为了更清楚,我添加了关系图(不包括工厂,不要将其作为有效的UML):

如您所见,我需要在我的ControllerFactory中使用$ serviceLocator-> getServiceLocator(),而不是在我的ServiceFactory中.为什么?
控制器工厂由不同的服务管理器实例("ControllerLoader")调用到主工厂.这使得调度程序不能导致主服务管理器实例化任意类.
因此,当您想要检索'greetingService'时,控制器工厂的$ serviceLocator不是您需要的那个,因为'greetingService'已向主服务管理器注册.要从控制器获取主服务器管理器,请使用getServiceLocator(),然后您将拥有主服务管理器的实例,您可以从中获取()'问候服务'
这被称为'对等'.即,将"主要服务管理器"作为对等体设置"ControllerLoader"服务管理器(通过配置中的"控制器"键配置的服务管理器或模块类中的getControllerConfiguration()).
| 归档时间: |
|
| 查看次数: |
22112 次 |
| 最近记录: |