Symfony2 - 如何使用从控制器外部访问服务

时间:2012-01-06 12:40:03

标签: symfony

在我的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 个答案:

答案 0 :(得分:16)

更新:Symfony不再正式推荐将控制器定义为服务。

get()类中的Controller方法只是从容器中获取服务的辅助方法,它的目的是让新的Symfony2开发人员加快速度。 一旦人们对框架和依赖注入感到满意,建议define controllers as services并明确注入每个必需的服务。

由于您的PersonChange类不是控制器且未扩展Controller类,因此您没有get()辅助方法。相反,您需要将您的类定义为服务并显式注入所需的服务。有关详细信息,请阅读Service Container chapter

答案 1 :(得分:12)

当我遇到完全相同的问题时,我可以帮忙

所说的什么是完美的,我只会尝试弹出现实生活中的例子。

就我而言,我想访问

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

即使通过扩展控制器,我也无法在控制器访问容器时让它工作(我仍然不明白为什么)

在config.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;
        }

然后你可以对$ this

使用get方法

答案 2 :(得分:6)

一种始终有效的方法,尽管不是OO的最佳实践

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

答案 3 :(得分:1)

如果您需要访问服务,请在类构造函数中定义它:

span

现在,您可以在调用类(示例1)时将Service作为参数传递,或者将clas本身定义为服务(推荐,示例2)

示例1:

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

示例2 (更好)

use Acme\PersonChange; class appController{ function buzzAction(){ $uploadManager = $this->get('upload.upload_manager'); $personChange = new PersonChange($uploadManager); 定义为服务本身,并将其他服务定义为services.yml文件中的参数:

PersonChange

通过这种方式,您不必为Controller中的 # app/config/services.yml services: upload.upload_manager: class: AppBundle\uploadManager PersonChange: class: AppBundle\PersonChange arguments: ['@upload.upload_manager'] 服务而烦恼,因为它被隐含地作为构造函数的参数传递,因此您的Controller可以是:

upload_manager