Как получить доступ к контейнеру службы в глобальной вспомогательной функции symfony2 (услуге)?

Этот вопрос начинался с того, что я не понимал, почему я не могу передать переменные в глобальную вспомогательную функцию symfony2 (service), но, благодаря людям ярче, чем я, я понял, что моя ошибка заключалась в попытке использовать security_context из класса, он не вводил так …

Это конечный результат, код, который работает. Я не нашел лучшего способа сделать это полезным для общения.

Таким образом вы можете получить пользовательские и другие данные из security_context из глобальной функции или вспомогательной функции в symfony2.

У меня есть следующий класс и функция:

<?php namespace BizTV\CommonBundle\Helper; use Symfony\Component\DependencyInjection\ContainerInterface as Container; class globalHelper { private $container; public function __construct(Container $container) { $this->container = $container; } //This is a helper function that checks the permission on a single container public function hasAccess($container) { $user = $this->container->get('security.context')->getToken()->getUser(); //do my stuff } } 

… определяется как служба (в app / config / config.yml), как это …

 #Registering my global helper functions services: biztv.helper.globalHelper: class: BizTV\CommonBundle\Helper\globalHelper arguments: ['@service_container'] 

Теперь, в моем контроллере, я вызываю эту функцию следующим образом …

 public function createAction($id) { //do some stuff, transform $id into $entity of my type... //Check if that container is within the company, and if user has access to it. $helper = $this->get('biztv.helper.globalHelper'); $access = $helper->hasAccess($entity); 

Solutions Collecting From Web of "Как получить доступ к контейнеру службы в глобальной вспомогательной функции symfony2 (услуге)?"

Я предполагаю, что первая ошибка (неопределенное свойство) произошла до того, как вы добавили свойство и конструктор. Затем вы получили вторую ошибку. Эта другая ошибка означает, что ваш конструктор ожидает получить объект Container, но ничего не получил. Это связано с тем, что, когда вы определили свой сервис, вы не сказали менеджеру по взысканию зависимостей, что вы хотите получить контейнер. Измените определение своего сервиса на это:

 services: biztv.helper.globalHelper: class: BizTV\CommonBundle\Helper\globalHelper arguments: ['@service_container'] 

Затем конструктор должен ожидать объект типа Symfony \ Component \ DependencyInjection \ ContainerInterface;

 use Symfony\Component\DependencyInjection\ContainerInterface as Container; class globalHelper { private $container; public function __construct(Container $container) { $this->container = $container; } 

Подход, который всегда работает, несмотря на то, что он не является лучшей практикой в ​​OO

 global $kernel; $assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');‏ 

Другой вариант – расширить ContainerAware:

 use Symfony\Component\DependencyInjection\ContainerAware; class MyService extends ContainerAware { .... } 

который позволяет вам вызвать setContainer в объявлении сервиса:

 foo.my_service: class: Foo\Bundle\Bar\Service\MyService calls: - [setContainer, [@service_container]] 

Затем вы можете ссылаться на контейнер в своей службе следующим образом:

 $container = $this->container; 

Может быть, это не лучший способ, но то, что я делаю, это передать контейнер классу, поэтому я получаю его каждый раз, когда мне это нужно.

 $helpers = new Helpers(); or $helpers = new Helpers($this->container); /* My Class */ class Helpers { private $container; public function __construct($container = null) { $this->container = $container; } ... } 

Работает каждый раз для меня.

Вы не должны вводить service_container в свои службы. В вашем примере вам следует скорее добавить старый security.context или более поздний security.token_storage . См. Например, раздел «Избегание вашего кода, зависящего от контейнера» в http://symfony.com/doc/current/components/dependency_injection.html .

Пример:

 <?php namespace BizTV\CommonBundle\Helper; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; class globalHelper { private $securityTokenStorage; public function __construct(TokenStorage $securityTokenStorage) { $this->securityTokenStorage= $securityTokenStorage; } public function hasAccess($container) { $user = $this->securityTokenStorage->getToken()->getUser(); //do my stuff } } 

приложение / Config / config.yml:

 services: biztv.helper.globalHelper: class: BizTV\CommonBundle\Helper\globalHelper arguments: ['@security.token_storage'] 

Ваш контроллер:

 public function createAction($id) { $helper = $this->get('biztv.helper.globalHelper'); $access = $helper->hasAccess($entity);