用户密码更改事件可以使用Doctrine preUpdate侦听器进行处理,但我无法执行另一个日志持久化过程,这会导致侦听器循环,因此错误跟踪如下所示:
Error: Maximum function nesting level of '5000' reached, aborting! in /var/www/my_project/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php line 85
我的preUpdate侦听器代码如下:
public function preUpdate(LifecycleEventArgs $args)
{
if (php_sapi_name()!='cli') {
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
// perhaps you only want to act on some "User" entity
if ($entity instanceof User) {
if($args->hasChangedField('password')){
//log as eventlog
$event = new \My_Project\UserBundle\Entity\EventLog();
$event->setEventInfo(UserEventLogParams::$PASSWORD_CHANGE);
$event->setIp($this->container->get('request')->getClientIp());
$event->setUserId($entity->getId());
$entityManager->persist($event);
$entityManager->flush();
}
}
}
}
这个问题在那里Adding additional persist calls to preUpdate call in Symfony 2.1进行了调整,但没有得到有效解决方案的回答。
如何使用Doctrine2事件监听器登录(使用mysql)密码更改事件?
我可以使用postUpdate方法吗?
答案 0 :(得分:0)
Doctrine Event System文档。 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#preupdate
此活动的限制:
- 刷新操作无法识别对已传递实体的关联的更改。
- 对已传递实体的字段的更改不再被刷新操作识别,使用传递给事件的计算变更集来修改原始字段值,例如,像上面的Alice to Bob示例一样使用
$eventArgs->setNewValue($field, $value);
。- 强烈建议不要对
醇>EntityManager#persist()
或EntityManager#remove()
进行任何调用,即使与UnitOfWork API结合使用,也不会在刷新操作之外按预期工作。
作为解决方案,您可以在changeSet
中抓取preUpdate
,但在EntityManager#persist()
中呼叫EntityManager#flush()
和postUpdate
。
另外,您需要使用监听器$事件的私有属性来获取postUpdate
函数。
privat $event;
public function preUpdate(LifecycleEventArgs $args)
{
if (php_sapi_name()!='cli') {
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
// perhaps you only want to act on some "User" entity
if ($entity instanceof User) {
if($args->hasChangedField('password')){
//log as eventlog
$this->event = new \My_Project\UserBundle\Entity\EventLog();
$this->event->setEventInfo(UserEventLogParams::$PASSWORD_CHANGE);
$this->event->setIp($this->container->get('request')->getClientIp());
$this->event->setUserId($entity->getId());
}
}
}
}
public function postUpdate(LifecycleEventArgs $args)
{
$entityManager = $args->getEntityManager();
$entityManager->persist($this->event);
$entityManager->flush();
}