我已经使用 Symfony 4 一段时间了,最近我为我的一个网页创建了一个 twig 扩展,它负责根据数据库中的数据翻译任何给定的字符串。不幸的是,我遇到了一个无法解决的奇怪问题。我会尝试按时间顺序写下发生的事情,这样更容易理解。
DatabaseTranslateExtension
注册一个新的|translate
在 Twig 中过滤。-
|translate
过滤器触发延迟加载TranslationService
待构建(当然,当它尚未构建时)。 TranslationService
只有一个实例创建(这是预期的)。- 构造函数会预加载数据,因此不会在每次翻译时都调用数据库。
- 过滤器调用
translate
方法,它要么翻译字符串,要么(如果数据库中没有翻译)将字符串添加到实例变量中,我们称之为stringsToTranslate
,这是一种数组类型 (String[]
)。 - 翻译完所有字符串后,应调用服务的析构函数,这会刷新
stringsToTranslate
数组存入数据库。
我最近意识到数据库中有很多重复项,因此我尝试调试应用程序并查看发生了什么。不知何故,我不知道这是可能的,服务的析构函数被调用两次,而不是一次。我很确定 Symfony 与它有关(可能是因为延迟加载)或它创建的一些反射类。我想知道是否有什么你能想到的,这会触发析构函数被调用两次(是的,它是一个类的完全相同的实例)。预先感谢您。
我确实在构建的应用程序中跟踪了代码,并找到了为我的服务创建的包装器,它调用了析构,这是代码:
public function __destruct()
{
$this->initializer2b670 || $this->valueHolder90d49->__destruct();
}
有趣的是这个__destruct
也被调用两次。似乎是因为还创建了 Reflection 类,并且两个类都调用了 destruct。
我确实转储了 __destructor
的 body 。第一次评价是false
,这意味着它需要在 valueHolder
上调用析构函数。类,然后再次调用它,评估结果为 true
(这可能也称为破坏)。奇怪。
最佳答案
如果有人遇到类似问题,请使用 KernelEvents::RESPONSE
或 KernelEvents::TERMINATE
而不是 __destructor
。
KernelEvent::RESPONSE
在发送响应之前触发。KernelEvent::TERMINATE
在发送响应后触发。
有关 Symfony 生命周期/事件的更多信息,请参见 here .
对于那些对多次调用 __destruct
感到好奇的人,这可能是因为在包装器之上创建的反射类。正常的类实例和反射的类实例被破坏,我可能会调用它几次。
关于php - Symfony 服务析构函数被多次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51030372/