[英]Zend Framework 2 Service in View Helper
我需要編寫一個視圖助手來獲取服務並使用它做一些事情。 我成功實現了視圖助手,可以訪問服務定位器。 問題是,當調用__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'部分中注冊的服務。 有沒有人知道如何訪問其他服務?
$this->getServiceLocator()
在視圖幫助器中只能獲取你需要使用的其他視圖助手$this->getServiceLocator()->getServiceLocator()
來獲取應用程序服務
@rafaame:我找到了一種在視圖Helper中訪問服務定位器的簡單方法
我們只是使用:
$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;
}
}
我猜你正在檢索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的視圖助手,因此沒有其他任何自動注入。
有了它,它將起作用
注入視圖助手的服務管理器似乎只有在模塊配置的“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;
}
它解決了這個問題,但對我來說這似乎是一個巨大的黑客攻擊。
在視圖助手中,如果要訪問應用程序服務,則使用
$this->getServiceLocator()->getServiceLocator()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.