php - ZF2 何时使用 getServiceLocator() 何时不使用

标签 php frameworks zend-framework2 service-locator

我真的很困惑什么时候使用 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):

Pseudo-UML

关于php - ZF2 何时使用 getServiceLocator() 何时不使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14911965/

相关文章:

javascript - 使用 css 删除行后表格中断

用于查询 unixODBC 的 PHP 脚本在浏览器中失败,但可以在 Linux 命令提示符下运行

java - 哪里可以免费找到 Encog 2 或用 Java 中的 Encog 3 进行神经网络编程,第二版

perl - 使用 Perl Test::More 时是否有函数名称约定?

javascript - ZF2-无法在 zend Framework 2 上使用 jQuery.ajax 访问 Controller 操作

php - 在 Zend Framework 的 2 InputFilter 中有条件地需要

php - 在选中复选框的位置插入数组

c# - 复合应用程序 block - 是否有合适的替代品可用?

cron - zend 框架 2 cron 操作

php - 使用 PHP 显示特定数量的文本