Мне нужно написать помощника вида, который получает услугу и что-то с ней делать. Я успешно реализовал помощник вида, чтобы иметь доступ к локатору службы. Проблема в том, что служба, которую я хочу получить, не обнаруживается через локатор службы при вызове метода __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()