View Helper中的Zend Framework 2服务

时间:2014-01-06 01:12:07

标签: php zend-framework2 zend-view

我需要编写一个视图助手来获取服务并使用它做一些事情。我成功实现了视图助手,可以访问服务定位器。问题是,当调用__invoke方法时,无法通过服务定位器找到我想要获取的服务。

视图助手代码:

<?php

namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper,
    Zend\ServiceManager\ServiceLocatorAwareInterface,

    Application\Model;

class LoggedCustomer extends AbstractHelper implements ServiceLocatorAwareInterface
{

    use \Zend\ServiceManager\ServiceLocatorAwareTrait;

    public function __invoke()
    {

        $model = new Model\Customer($this->getServiceLocator());

        return $model->getCurrent();

    }

}

模型代码的片段:

namespace Application\Model;

use Application\Entity,
    Andreatta\Model\Base as Base;

class Customer extends Base
{

    /**
     * 
     * @return Zend\Authentication\AuthenticationService
     */
    public function getAuthService()
    {

        $serviceLocator = $this->getServiceLocator();

        return $serviceLocator->get('Application\Auth');

    }

    /**
     * 
     * @return Zend\Authentication\Adapter\AdapterInterface
     */
    protected function getAuthAdapter()
    {

        return $this->getAuthService()->getAdapter();

    }

    public function getCurrent()
    {

        $authService = $this->getAuthService();

        if ($authService->hasIdentity())
            return $authService->getIdentity();

        return null;

    }

module.config.php的片段:

'service_manager' => array
(

    'factories' => array
    (

        'Application\Auth' => function($sm)
        {

            $authService = $sm->get('doctrine.authenticationservice.application');
            $authService->setStorage( new \Zend\Authentication\Storage\Session('Application\Auth'));

            return $authService;

        },

    ),

),

'view_helpers' => array
(

    'invokables' => array
    (

        'loggedCustomer' => 'Application\View\Helper\LoggedCustomer',

    ),

),

从任何视图调用视图助手时,我得到以下内容:

Zend\View\HelperPluginManager::get was unable to fetch or create an instance for Application\Auth

奇怪的是应用程序运行正常(即该服务通常由应用程序的其他部分使用)。

编辑:

我做了一些研究,我认为我可以通过视图助手中的服务管理器访问的唯一服务是在module.config.php的'view_manager'部分中注册的服务。有没有人知道如何访问其他服务?

5 个答案:

答案 0 :(得分:13)

视图助手中的

$this->getServiceLocator()只能获取您需要使用$this->getServiceLocator()->getServiceLocator()获取应用程序服务的其他视图助手

答案 1 :(得分:7)

@rafaame:我找到了一种在视图助手中访问服务定位器的简单方法

我们只是使用:

$this->getView()->getHelperPluginManager()->getServiceLocator(); 

获取服务定位器 示例视图助手:

namespace Tmcore\View\Helper;

use Zend\View\Helper\AbstractHelper;

class Resource extends AbstractHelper
{
    public function adminResource()
    {
        $sm = $this->getView()->getHelperPluginManager()->getServiceLocator();
        $adminConfig = $sm->get('ModuleManager')->loadModule('admin')->getConfig();
        return $adminConfig;
    }
}

答案 2 :(得分:3)

我猜您正在检索Zend\View\HelperPluginManager而不是正确的ServiceManager。 可能你没有按照自己的意愿注射它。

如果那是你的完整LoggedCustomer代码,那是有道理的,因为你没有保存SM。据我所知,如果你实现了ServiceLocatorAwareInterface,SM将被注入,但你必须处理它。

更新:

抱歉,我没有意识到你有ServiceLocatorAwareTrait;那是一样的。

但是,阅读http://framework.zend.com/manual/2.0/en/modules/zend.service-manager.quick-start.html 我明白了

  

默认情况下,Zend Framework MVC注册一个初始化程序,它将注入ServiceManager实例,这是一个实现   Zend \ ServiceManager \ ServiceLocatorInterface,进入任何类   实现Zend \ ServiceManager \ ServiceLocatorAwareInterface。一个   简单的实现如下所示。

因此,如果在控制器中实现ServiceLocatorAwareInterface,则仅注入服务管理器。

因此,您应该手动注入服务管理器。

为此,我用来做的是在Module.php中创建一个工厂,而不是在配置中创建invokable。为此你实现了这个功能:

   public function getViewHelperConfig()
   {
    return array(
        'factories' => array(
                'loggedCustomer' => function($sm) {


                     $vh = new View\Helper\LoggedCustomer();
                     $vh->setServiceLocator($sm->getServiceLocator());

                      return $vh;

                  }
             );
      }

另外,我没有实现ServiceLocatorAwareInterface的视图助手,因此没有其他任何内容被自动注入。

有了它,它将起作用

答案 3 :(得分:1)

注入视图助手的服务管理器似乎只有在模块配置的“view_manager”部分中注册的服务。

可以通过将视图助手注册为像这样的工厂来注入“主”服务管理器:

'view_helpers' => 
[

    'factories' =>
    [

        'loggedCustomer' => function($pluginManager)
        {

            $serviceLocator = $pluginManager->getServiceLocator();

            $viewHelper = new View\Helper\LoggedCustomer();
            $viewHelper->setServiceLocator($serviceLocator);

            return $viewHelper;

        },

    ]

],

但是你必须确保在视图助手中的setServiceLocator方法中对它进行处理。否则,“受限”服务管理器将在稍后注入视图助手。像这样:

public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{

    if($this->serviceLocator !== null)
        return $this;

    $this->serviceLocator = $serviceLocator;

    return $this;
}

它解决了这个问题,但对我来说这似乎是一个巨大的攻击。<​​/ p>

答案 4 :(得分:0)

在视图助手中,如果要访问应用程序服务,请使用

$this->getServiceLocator()->getServiceLocator()