我是Symfony的新手并关注the Jobeet tutorial。我有三个实体 - 工作,类别和用户。我有以下服务监听器。
的src / IBW / JobeetBundle /资源/配置/ services.yml
services:
ibw.jobeet.entity.job.container_aware:
class: Ibw\JobeetBundle\Doctrine\Event\Listener\JobListener
calls:
- [setContainer, ["@service_container"]]
tags:
- { name: doctrine.event_listener, event: postLoad }
的src / IBW / JobeetBundle /学说/事件/侦听/ JobListener.php
<?php
namespace Ibw\JobeetBundle\Doctrine\Event\Listener;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
class JobListener
{
/** @var ContainerInterface */
protected $container;
/**
* @param ContainerInterface @container
*/
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @ORM\PostLoad
*/
public function postLoad(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if (method_exists($entity, 'setContainer')) {
$entity->setContainer($this->container);
}
}
}
我预计只会为作业实体调用postLoad
,但我发现其他两个实体类别和用户即可。我只在作业实体中定义setContainer
。所以,我得到了其他实体的未定义方法。我的解决方法是与method_exists
核对。
有没有办法只在特定实体上运行postLoad
?
答案 0 :(得分:3)
更新的答案
您的示例是一个事件监听器,但根据您的说明,您需要entity listener以下结帐示例。
- 实体侦听器可以是任何类,默认情况下它应该是一个带有无参数构造函数的类。
- 与实现事件监听器不同,实体监听器仅调用指定的实体。
- 实体侦听器方法接收两个参数,即实体实例和生命周期事件。
<强>实体强>
namespace Your\WhateverBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\EntityListeners({"Your\WhateverBundle\EntityListener\JobListener"})
* @ORM\Table(name="job")
*/
class Job
{
// Your properties, getters and setters
}
<强> EntityListener 强>
namespace Your\WhateverBundle\EntityListener;
use Your\WhateverBundle\Entity\Job;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping as ORM;
class JobListener
{
/** @ORM\PostLoad */
public function postLoadHandler(Job $job, LifecycleEventArgs $args)
{
// Do whatever you want
}
}
答案 1 :(得分:2)
如果您正在运行Doctrine 2.4或更高版本,则可以使用Entity listener而不是事件侦听器。这仅由与其关联的实体或实体触发。我已经在Symfony中成功使用了这个,尽管我现在无法访问我的代码。这是一个example,虽然它错过了将听众与相关实体联系起来的重要部分。我认为只需要根据Doctrine文档将@EntityListeners({“监听器服务名称”})添加到@Entity注释块(或XML或YAML,如果您没有使用注释)。我会稍后检查我的代码并更正是否需要更多代码。
答案 2 :(得分:1)
显然,Listener类必须放在Entity类的旁边。 使用这样的目录结构,以及以下配置,它似乎像魅力一样。
# src/vendor/yourBundle/Entity/JobListener.php
namespace VENDOR\YourBundle\Entity;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use VENDOR\YourBundle\Entity\Job;
/**
* Class JobListener
* @package VENDOR\YourBundle\Entity
*/
class JobListener {
public function postLoad( Job $job, LifecycleEventArgs $args ) {
.....
}
}
# src/vendor/yourBundle/Resources/config/doctrine/Job.orm.yml
VENDOR\YourBundle\Entity\Job:
type: entity
...
entityListeners:
VENDOR\YourBundle\Entity\JobListener: ~
...
或者您更喜欢注释
# src/vendor/yourBundle/Entity/Job.php
/**
* @ORM\Entity
* @ORM\EntityListeners({"VENDOR\YourBundle\Entity\JobListener"})
*/
class Job {
.....
}
如果必须向Listener中注入一些服务,则必须添加一些类似的配置。
# app/config/services.yml
# or
# src/vendor/yourBundle/Resources/config/services.yml
doctrine.job_listener:
class: Vendor\YourBundle\Entity\JobListener
arguments: ["Path\To\Your\Service"]
tags:
- { name: doctrine.orm.entity_listener }