簡體   English   中英

View Helper中的Zend Framework 2服務

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM