我正在尝试从 Doctrine 2 中的实体外部禁用实体事件。每次我们将新记录插入表中时,都需要运行很少的文件操作,这些操作已在具有 prePersist 注释的方法中实现。但是,我还需要运行一些数据夹具并跳过文件操作部分作为测试的一部分。基本上我在问是否可以通过实体管理器禁用所有 prePersist 事件而不更改实体中的任何内容。
提前致谢。
我正在尝试从 Doctrine 2 中的实体外部禁用实体事件。每次我们将新记录插入表中时,都需要运行很少的文件操作,这些操作已在具有 prePersist 注释的方法中实现。但是,我还需要运行一些数据夹具并跳过文件操作部分作为测试的一部分。基本上我在问是否可以通过实体管理器禁用所有 prePersist 事件而不更改实体中的任何内容。
提前致谢。
如果您可以完全删除生命周期回调,那么您可以手动清除回调。这在动态夹具生成的情况下很有用。你只需这样做:
$this->em->getClassMetadata(get_class($object))->setLifecycleCallbacks(array());
感谢 Jeremy Mikola ( @jmikola ) 为我指明了正确的方向。
JimTheDev 的解决方案实际上效果很好。
在我的一个测试类中,我有这个方法:
private function persistSkippingEvents($object, $manager)
{
// temporarily stores lifecycle events
$events = $manager->getClassMetadata(get_class($object))->lifecycleCallbacks;
// removes lifecycle events
$manager->getClassMetadata(get_class($object))->setLifecycleCallbacks(array());
$manager->persist($object);
$manager->getClassMetadata(get_class($object))->setLifecycleCallbacks($events);
}
使用 ORM API 无法禁用生命周期回调。
问题来自于在调用实体的生命周期回调之后调用外部侦听器的事实,因此即使是禁用回调的瞬态属性(由外部侦听器/订阅者设置)也不起作用。
考虑将逻辑从实体移动到外部侦听器/订阅者:这样,您将获得更大的灵活性,并且您可以通过重用侦听器/订阅者本身的内部状态来关闭您描述的行为。
// ...
public function prePersist(LifecycleEventArgs $args)
{
if ($this->skipCondition($args->getEntity()) {
return;
}
$this->manipulate($args->getEntity());
}
// ...