Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Symfony观察者模式-设置实体属性时如何分派自定义事件?_Php_Symfony_Events_Doctrine_Observer Pattern - Fatal编程技术网

Php Symfony观察者模式-设置实体属性时如何分派自定义事件?

Php Symfony观察者模式-设置实体属性时如何分派自定义事件?,php,symfony,events,doctrine,observer-pattern,Php,Symfony,Events,Doctrine,Observer Pattern,是否有一种方法可以在每次调用某个实体setter时分派自定义事件 我实际上需要更改一个无关实体的某些值,每次更改某个实体属性时。因此,为了分离关注点和解耦对象,我想使用观察者模式来实现这一点。我不想在诸如“preUpdate”或类似事件中这样做,因为它们只在实体刷新时触发,但我需要立即更改此值以确保这两个值始终同步 由于向实体中注入任何服务都是不好的做法,我不知道如何才能做到这一点 有什么建议吗?使用事件调度程序: 传递您信息的事件 class UpdateEntityEvent extends

是否有一种方法可以在每次调用某个实体setter时分派自定义事件

我实际上需要更改一个无关实体的某些值,每次更改某个实体属性时。因此,为了分离关注点和解耦对象,我想使用观察者模式来实现这一点。我不想在诸如“preUpdate”或类似事件中这样做,因为它们只在实体刷新时触发,但我需要立即更改此值以确保这两个值始终同步

由于向实体中注入任何服务都是不好的做法,我不知道如何才能做到这一点


有什么建议吗?

使用事件调度程序:

传递您信息的事件

class UpdateEntityEvent extends Event {
     private $myEntity;
     private $newValue;

     public function __construct(Entity $entity, Whatever $newValue){
         $this->myEntity = $entity;
         $this->newValue = $newValue;
    }
  // [...] getters
}
你的听众

class UpdateMyEntityEventListener
{
    public function updateCertainProperty(UpdateMyEntityEvent $event)
    {
        // Do what you want here :D
    }
}
一些配置

 kernel.listener.updateMyEntity:
     class: Acme\AppBundle\EventListener\UpdateMyEntityEventListener
     tags:
         - { name: kernel.event_listener, event: updateMyEntity, method: updateCertainProperty }
我们避免使用硬编码字符串,让我们将事件名称放在常量中

class MyEntityEvents 
{
    const UPDATE = 'updateMyEntity';
}
然后在你的控制器里

public function updateAction()
{
    // [...]
    $event = new UpdateMyEntityEvent($entity, $whatever);
    $dispatcher = $this->get('event_dispatcher')->dispatch( MyEntityEvents::UPDATE, $event);

如果您希望使用observer模式,您必须以某种方式自己实现它。正如您所指出的,只有在触发刷新操作时,条令才会计算实体的变更集,而不是之前。话虽如此,但该学说恰好提出了这一点。
NOTIFY
跟踪策略行为完全取决于您希望实现的目标

我不是建议您更改实体的跟踪策略,而是建议您可以利用现有接口来实现您的观察者模式。如前所述,要做到这一点,被观察的实体需要实现接口

从那里,您可以直接在另一个实体中实现接口(或者使用一个特定的服务,该服务将在
postLoad
事件中添加自己作为您的实体的侦听器)。在这里,它主要取决于实体之间的关系以及如何将侦听器附加到实现
NotifyPropertyChanged
的实体


请注意,如果您这样做,条令的
UnitOfWork
将自动挂接自己作为实体的侦听器,但只要您不添加
@ChangeTrackingPolicy(“NOTIFY”)
注释,它仍将依赖于自动变更集计算。

是的,将服务注入实体是非常糟糕的做法。我不明白您为什么要记录不会刷新到DB的更改?我并没有说它不会刷新,我只是说我需要它同步,即使“尚未”刷新。您可以将您的实体包装到注入事件调度器的自定义服务中。该服务将在属性更改时发送自定义事件。是的,您是对的。但我在很多地方使用这个实体,没有任何服务,所以我希望我不必改变所有这些。。。我想我必须这么做。谢谢你。我理解你的提议。但这就是为什么这对我来说不是一个真正的解决方案:。。。我有许多控制器更新该属性,我必须将事件调度添加到所有控制器中。如果我忘记了一个,或者如果我从现在开始编写一个新的,我会记得这样做吗?我可以在使用persist/flush方法时说同样的话:我有许多控制器更新我的实体,如果我忘记了flush怎么办?我会记得那样做吗P您可以使用另一个服务,如EntityManager,并使用一个方法
updateMyEntity()
,该方法可以将此逻辑保持在内部。但是如何以及何时添加侦听器呢?或者我可以在一个视频中捕捉事件吗?怎么做?就像我说的,这取决于你们两个实体之间的关系。到底是什么,有联系吗?没有联系。我有一个包含order和orderItem实体的电子商务包,现在我想在其中添加一个库存系统(解耦)。库存系统需要了解订单的任何数量变化。不知怎的,我觉得这样做是错误的。。。但是非常感谢你的帮助。