我不是在写#34;我尝试了什么"或者"什么不起作用"因为我可以想到很多方法来实现这样的东西。但我无法相信以前没有人做过类似的事情,这就是为什么我想问这个问题,看看哪种Doctrine2最佳实践出现了。
我想要的是触发房产变更事件。因此,我们假设我有一个$active
属性的实体,当属性从EntityBecameActive
更改为false
时,我希望为每个实体触发true
个事件
其他库通常有PropertyChanged
个事件,但Doctrine2中没有这样的东西。
所以我有这样的实体:
<?php
namespace Application\Entity;
class Entity
{
/**
* @var int
* @ORM\Id
* @ORM\Column(type="integer");
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var boolean
* @ORM\Column(type="boolean", nullable=false)
*/
protected $active = false;
/**
* Get active.
*
* @return string
*/
public function getActive()
{
return $this->active;
}
/**
* Is active.
*
* @return string
*/
public function isActive()
{
return $this->active;
}
/**
* Set active.
*
* @param bool $active
* @return self
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
}
答案 0 :(得分:3)
也许ChangeTracking政策就是你想要的,也许不是!
NOTIFY政策基于实体通知的假设 感兴趣的听众改变他们的财产。为了这个目的, 想要使用此策略的类需要实现 来自Doctrine \ Common命名空间的NotifyPropertyChanged接口。
查看上面链接中的完整示例。
class MyEntity extends DomainObject
{
private $data;
// ... other fields as usual
public function setData($data) {
if ($data != $this->data) { // check: is it actually modified?
$this->onPropertyChanged('data', $this->data, $data);
$this->data = $data;
}
}
}
<强>更新强>
这是一个完整的例子,但很傻,所以你可以按照自己的意愿工作。它只是演示了你是如何做到的,所以不要太认真!
<强>实体强>
namespace Football\TeamBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="country")
*/
class Country extends DomainObject
{
/**
* @var int
*
* @ORM\Id
* @ORM\Column(type="smallint")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(type="string", length=2, unique=true)
*/
protected $code;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set code
*
* @param string $code
* @return Country
*/
public function setCode($code)
{
if ($code != $this->code) {
$this->onPropertyChanged('code', $this->code, $code);
$this->code = $code;
}
return $this;
}
/**
* Get code
*
* @return string
*/
public function getCode()
{
return $this->code;
}
}
<强> domainObject的强>
namespace Football\TeamBundle\Entity;
use Doctrine\Common\NotifyPropertyChanged;
use Doctrine\Common\PropertyChangedListener;
abstract class DomainObject implements NotifyPropertyChanged
{
private $listeners = array();
public function addPropertyChangedListener(PropertyChangedListener $listener)
{
$this->listeners[] = $listener;
}
protected function onPropertyChanged($propName, $oldValue, $newValue)
{
$filename = '../src/Football/TeamBundle/Entity/log.txt';
$content = file_get_contents($filename);
if ($this->listeners) {
foreach ($this->listeners as $listener) {
$listener->propertyChanged($this, $propName, $oldValue, $newValue);
file_put_contents($filename, $content . "\n" . time());
}
}
}
}
<强>控制器强>
namespace Football\TeamBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Football\TeamBundle\Entity\Country;
class DefaultController extends Controller
{
public function indexAction()
{
// First run this to create or just manually punt in DB
$this->createAction('AB');
// Run this to update it
$this->updateAction('AB');
return $this->render('FootballTeamBundle:Default:index.html.twig', array('name' => 'inanzzz'));
}
public function createAction($code)
{
$em = $this->getDoctrine()->getManager();
$country = new Country();
$country->setCode($code);
$em->persist($country);
$em->flush();
}
public function updateAction($code)
{
$repo = $this->getDoctrine()->getRepository('FootballTeamBundle:Country');
$country = $repo->findOneBy(array('code' => $code));
$country->setCode('BB');
$em = $this->getDoctrine()->getManager();
$em->flush();
}
}
让此文件具有777权限(再次,这是测试):src/Football/TeamBundle/Entity/log.txt
当您运行代码时,您的日志文件中将存储时间戳,仅用于演示目的。