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 

Странно то, что приложение работает правильно (т. Е. Эта служба обычно используется другими частями приложения).

РЕДАКТИРОВАТЬ:

Я провел некоторое исследование, и я думаю, что единственными услугами, которые я могу получить через диспетчера служб внутри помощника вида, являются те, которые зарегистрированы в разделе «view_manager» module.config.php. Кто-нибудь имеет представление о том, как получить доступ к другим услугам?

$this->getServiceLocator() в $this->getServiceLocator() может получить только другие помощники вида, для которых вам нужно использовать $this->getServiceLocator()->getServiceLocator() чтобы получить сервисы приложений

@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; } } 

Я предполагаю, что вы 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()