【发布时间】:2016-02-27 19:38:08
【问题描述】:
在 Doctrine 2.4 之前,捕获生命周期事件(如 prePersist)的默认方式是全局 event listener,它将为所有实体触发。将这样的监听器作为 Symfony 服务运行可以很容易地注入其他服务(如 request 或 request_stack 对象)。
现在更好的解决方案似乎是 entity listener,因为它的开销要少得多!
所以让我们在实体标题中开始这件事...:
* @ORM\EntityListeners({ "AppBundle\Entity\Listener\LanguageListener" })
这是课程:
namespace AppBundle\Entity\Listener;
use Doctrine\ORM\Event\LifecycleEventArgs;
class LanguageListener
{
public function prePersist($obj_entity, LifecycleEventArgs $obj_eventArgs)
{
$request = ???;
// set entity to users preferred language (for example 'de')
$obj_entity->setLanguage($request->getLocale());
}
}
如你所见,我一点也不知道如何访问 Symfonys 服务(在本例中为 request 对象)。
但是等等!有一个办法:
global $kernel;
if ('AppCache' == get_class($kernel))
{
$kernel = $kernel->getKernel();
}
$request = $kernel->getContainer()->get('request');
而且它也很有效。
但在我所有的研究中,我发现了很多相关的问题,这些问题都严格警告了这一点! 唯一的区别:所有这些问题都是针对 Entities,而不是 Entity listeners...
...引导我提出这两个问题:
- 上述解决方案是否可行?
- 如果没有:应该怎么做?
[编辑:] 再次(见第一句话)让我明确指出,这个问题也是关于如何不使用服务。服务需要付费,请参阅Expensive Service Construction。尤其是在这种情况下,我很少需要该功能 - 这就是为什么我想使用不作为服务运行的实体侦听器。
抱歉,我没有过分强调这一方面。不知道为什么这符合降价的条件......
[Edit2:] 为了让事情更清楚,我添加了一个代码示例(第一个),显示了事物是如何映射的。
【问题讨论】:
-
你已经看到Entity listeners resolver了吗?
-
我认为这是结合 symfony 方式的解决方案 Entity Listeners
-
可能是,我还没有真正掌握解析器的概念。不过今天早些时候读过,很好读:Entity Listener Resolver 但无论如何这仍然不能解决我的问题。
-
据我所知,让服务接受容器作为参数被认为是不好的做法。您应该改为传递您需要的服务。 @Matteo 的方法是 Eddie 应该做的事情。
标签: php symfony doctrine-orm entitylisteners