如何在Symfony2中添加可访问容器

时间:2015-05-27 17:09:28

标签: php symfony doctrine-orm

在Symfony2应用程序中,我有一个实体,需要在预先持久化时填充各种上下文属性(如用户ID,调用它的页面等)。

我认为要做到这一点,我需要添加一个可以访问" service_container"的教义事件监听器,并且提供这种访问的最佳方式是通过" service_container"作为这个听众的论据。

我有一个我想听的特定实体,我不想触发与任何其他实体的事件的监听器。

我们可以添加特定于实体的侦听器,文档可在此处找到: http://docs.doctrine-project.org/en/latest/reference/events.html#entity-listeners   - 但这不提供如何传递参数的示例(我使用PHP注释来声明侦听器)。

我还尝试使用JMSDiExtraBundle注释,如下例所示: http://jmsyst.com/bundles/JMSDiExtraBundle/master/annotations#doctrinelistener-or-doctrinemongodblistener   - 但这种方式需要将侦听器声明为非特定于实体的

有没有办法只为一个实体创建一个侦听器,并让它可以访问容器?

2 个答案:

答案 0 :(得分:1)

我只是从事件中检查实体类型。如果检查订户内部或外部的类型,则其性能成本相同。简单的类型条件足够快。

namespace App\Modules\CoreModule\EventSubscriber;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Events;


class SetCountryToTaxSubscriber implements EventSubscriber
{

    /**
     * {@inheritdoc}
     */
    public function getSubscribedEvents()
    {
        return [Events::prePersist];
    }


    public function prePersist(LifecycleEventArgs $lifecycleEventArgs)
    {
        $entity = $lifecycleEventArgs->getEntity();
        if ( ! $entity instanceof Tax) {
            return;
        }

        $entity->setCountry('myCountry');
    }

}

答案 1 :(得分:1)

通过依赖注入与doctrine docs类似的方法之一:

<?php

namespace AppBundle\EntityListener;

use AppBundle\Entity\User;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use Psr\Log\LoggerInterface;
use Symfony\Component\Routing\RouterInterface;

class UserListener {

    /**
     * @var LoggerInterface
     */
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function postPersist(User $user, LifecycleEventArgs $args)
    {
        $logger = $this->logger;

        $logger->info('Event triggered');

        //Do something
    }
}
services:
  user.listener:
      class: AppBundle\EntityListener\UserListener
      arguments: [@logger]
      tags:
          - { name: doctrine.orm.entity_listener }

并且不要忘记将侦听器添加到实体映射:

AppBundle\Entity\User:
    type: entity
    table: null
    repositoryClass: AppBundle\Entity\UserRepository
    entityListeners:
        AppBundle\EntityListener\UserListener: ~