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



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



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



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



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



<?php
namespace BizTVCommonBundleHelper;

use SymfonyComponentDependencyInjectionContainerInterface 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: BizTVCommonBundleHelperglobalHelper
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);
645   5  

5 ответов:

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

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

app / 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);

Comments

    Ничего не найдено.