我需要编写一个视图助手来获取服务并使用它做一些事情。我成功实现了视图助手,可以访问服务定位器。问题是,当调用__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'部分中注册的服务。有没有人知道如何访问其他服务?
答案 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()