【发布时间】:2018-12-04 10:28:25
【问题描述】:
我玩 Symfony 4 已经有一段时间了,最近我为我的一个网页创建了一个 twig 扩展,它负责根据数据库中的数据翻译任何给定的字符串。不幸的是,我遇到了一个我无法解决的奇怪问题。我会尝试按时间顺序写下发生的事情,这样更容易理解。
-
DatabaseTranslateExtension在 Twig 中注册了一个新的|translate过滤器。 -
|translate过滤器触发 延迟加载TranslationService被构造(当然,当它尚未构造时)。 - 仅创建了一个
TranslationService实例(这是预期的)。 - 构造函数会预加载数据,因此不会在每次转换时都调用数据库。
- 过滤器调用
translate方法,该方法要么翻译字符串,要么(如果数据库中没有翻译)将字符串添加到实例变量中,我们称之为stringsToTranslate,这是一种数组(@987654328 @)。 - 翻译完所有字符串后,应该调用服务的析构函数,这会将
stringsToTranslate数组刷新到数据库中。
我最近意识到数据库中有很多重复项,因此我尝试调试应用程序并查看发生了什么。不知何故,我什至不知道这是可能的,服务的析构函数被调用了两次,而不是一次。我很确定 Symfony 与它有关(可能是因为延迟加载)或它创建的一些反映类。我想知道是否有什么你能想到的,这会触发析构函数被调用两次(是的,它是一个类的完全相同的实例)。提前谢谢你。
我确实在构建的应用程序中跟踪了代码,并找到了为我的服务创建的包装器,它调用了 destruct,代码如下:
public function __destruct()
{
$this->initializer2b670 || $this->valueHolder90d49->__destruct();
}
有趣的是这个__destruct也被调用了两次。似乎是因为还创建了 Reflection 类,并且这两个类都调用了 destruct。
我确实倾倒了__destructor 的尸体。第一次评估是false,这意味着它需要在valueHolder 类上调用destruct,然后再次调用它评估为true(可能也称为destruct)。很奇怪。
【问题讨论】:
-
尽管 php 的析构函数有点不稳定。您是否考虑过在 kernel.terminate 侦听器中进行刷新?
-
感谢您指出。我可能需要为此创建一个 EventListener,但我认为使用析构函数来做这件事是一个不错的尝试。我个人并不经常使用它们,所以我认为当我有机会并且情况需要析构函数提供的那种行为时,最终尝试它可能会很好。不过,这是一些非常奇怪的东西,我的意思是..你怎么可能两次摧毁同样的东西?没关系,再次感谢您的建议
-
有一些关于析构函数的旧帖子被多次调用,但最近没有。通常我会说您创建了两个实例(可能通过 _profile 栏),但您表示情况并非如此。我认为这只发生在生产模式下。
标签: php symfony service destructor symfony4