Symfony2-Как использовать доступ к службе извне контроллера - PullRequest
15 голосов
/ 06 января 2012

В моем контроллере Symfony2 это работает нормально:

$uploadManager = $this->get('upload.upload_manager');

, но когда я перемещаю его в пользовательский прослушиватель:

use Doctrine\ORM\Event\LifecycleEventArgs;
use Acme\UploadBundle\Upload\UploadManager;

class PersonChange
{
    public function postRemove(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        $entityManager = $args->getEntityManager();

        $uploadManager = $this->get('ep_upload.upload_manager');
        echo "the upload dir is " . $uploadManager->getUploadDir();
    }
}

Я получаю ошибку:

Fatal error: Call to undefined method Acme\MainBundle\Listener\PersonChange::get() in /home/frank/...

Я знаю, что мне нужно заявление об использовании, но не знаю, что использовать.

Ответы [ 4 ]

16 голосов
/ 06 января 2012

Обновление: определение контроллеров как сервисов больше не рекомендуется в Symfony.

Метод get() в классе Controller - это просто вспомогательный метод для получения служб из контейнера, и он должен был ускорить работу новых разработчиков Symfony2. Как только люди освоятся с внедрением инфраструктуры и зависимостей, рекомендуется определить контроллеры как службы и явно внедрить каждую требуемую службу.

Поскольку ваш класс PersonChange не является контроллером и не расширяет класс Controller, у вас нет этого вспомогательного метода get(). Вместо этого вам нужно определить свой класс как сервис и явно добавить необходимые сервисы. Подробнее см. Главу Сервисный контейнер .

12 голосов
/ 06 января 2012

Когда я столкнулся с точно такой же проблемой, может быть, я смогу помочь

То, что сказал Эльнур, прекрасно, и я просто попытаюсь привести пример из реальной жизни.

В моем случаеЯ хотел получить доступ к

$lucenemanager = $this->get('ivory.lucene.manager')

Даже при расширении контроллера я не мог заставить его работать, пока контроллер действительно обращался к контейнеру (я до сих пор не понял, почему)

В конфигурации.yml мой слушатель (searchindexer.listener) объявлен следующим образом:

   services:
    searchindexer.listener:
        class: ripr\WfBundle\Listener\SearchIndexer
        arguments:
              luceneSearch: "@ivory_lucene_search"
        tags:
            - { name: doctrine.event_listener, event: postPersist }

Служба (ivory.lucene.search) передается в качестве аргумента в моем сервисе / слушателе.

Тогда в моем классе

protected $lucenemanager;

        public function __construct($luceneSearch)
        {
            $this->lucenemanager = $luceneSearch;
        }

Тогда вы можете использовать метод get против $ this

6 голосов
/ 02 апреля 2014

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

global $kernel;
$assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');‏
1 голос
/ 18 февраля 2016

Если вам нужен доступ к Сервису, определите его в конструкторе класса:

class PersonChange{
    protected $uploadManager;
    public function __construct(UploadManager $uploadManager){
        $this->uploadManager = $uploadManager;
    }
    // Now you can use $this->uploadManager.
}

Теперь вы можете передать Сервис в качестве аргумента при вызове класса (пример 1) или определить сами классы какСлужба ( рекомендуется , пример 2)

Пример 1:

use Acme\PersonChange;
class appController{
    function buzzAction(){
        $uploadManager = $this->get('upload.upload_manager');
        $personChange = new PersonChange($uploadManager);

Пример 2 (лучше) :

ОпределитьPersonChange как саму Службу и определите другую Службу в качестве аргумента в файле services.yml:

 # app/config/services.yml
services:
    upload.upload_manager:
        class:     AppBundle\uploadManager

    PersonChange:
        class:     AppBundle\PersonChange
        arguments: ['@upload.upload_manager']

Таким образом, вам не нужно беспокоиться о службе upload_manager вКонтроллер, поскольку он неявно передается в качестве аргумента для конструктора, поэтому ваш Контроллер может быть:

class appController{
    function buzzAction(){
        $personChange = $this->get('PersonChange');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...