Php 多次调用Symfony服务析构函数

Php 多次调用Symfony服务析构函数,php,symfony,service,destructor,symfony4,Php,Symfony,Service,Destructor,Symfony4,我使用symfony4已经有一段时间了,最近我为我的一个网页创建了一个小树枝扩展,它负责根据数据库中的数据翻译任何给定的字符串。不幸的是,我遇到了一个我无法解决的奇怪问题。我将试着按时间顺序写下发生的事情,这样更容易理解 DatabaseTranslateExtension在Twig中注册一个新的|translate过滤器 |translate过滤器触发要构造的延迟加载的TranslationService(当然,当尚未构造时) 只创建了一个TranslationService实例(这是预期的)

我使用symfony4已经有一段时间了,最近我为我的一个网页创建了一个小树枝扩展,它负责根据数据库中的数据翻译任何给定的字符串。不幸的是,我遇到了一个我无法解决的奇怪问题。我将试着按时间顺序写下发生的事情,这样更容易理解

  • DatabaseTranslateExtension
    在Twig中注册一个新的
    |translate
    过滤器
  • |translate
    过滤器触发要构造的延迟加载的
    TranslationService
    (当然,当尚未构造时)
  • 只创建了一个
    TranslationService
    实例(这是预期的)
  • 构造函数预加载数据,所以它不会在每次转换发生时调用数据库
  • 过滤器调用
    translate
    方法,该方法要么翻译字符串,要么(如果数据库中没有翻译)将字符串添加到实例变量中,我们将其称为
    stringsToTranslate
    ,这是一种数组(
    string[]
  • 翻译完所有字符串后,应该调用服务的析构函数,它会将
    stringsToTranslate
    数组刷新到数据库中
  • 我最近意识到数据库中有很多重复项,所以我试着调试应用程序,看看发生了什么。不知何故,我甚至不知道这是可能的,服务的析构函数被调用了两次,而不是一次。我很确定Symfony与此有关(可能是因为延迟加载),或者与它创建的一些反射类有关。我想知道是否有什么方法可以触发析构函数被调用两次(是的,它是一个类的完全相同的实例)。先谢谢你


    我确实在一个内置的应用程序中找到了代码,并找到了为我的服务创建的包装,它调用了析构函数,下面是代码:

    public function __destruct()
    {
        $this->initializer2b670 || $this->valueHolder90d49->__destruct();
    }
    
    有趣的是,这个
    \uu destruct
    也被调用了两次。这似乎是因为还创建了反射类,这两个类都调用析构函数。
    我确实转储了
    \u析构函数的主体。第一次求值是
    false
    ,这意味着它需要调用
    valueHolder
    类上的析构函数,然后再次调用求值为
    true
    (这可能也调用了析构函数)。奇怪。

    如果有人有类似的问题,请使用
    KernelEvents::RESPONSE
    KernelEvents::TERMINATE
    而不是
    \u destructor

    • KernelEvent::RESPONSE
      在发送响应之前被激发
    • KernelEvent::TERMINATE
      在发送响应后被激发
    有关Symfony生命周期/事件的更多信息,请参见



    对于那些对多次调用
    \uuu destruct
    感到好奇的人来说,这可能是因为在包装器上创建了反射类。普通类实例和反射类实例被析构函数分解,我可能多次调用过它。

    尽管php的析构函数有点古怪。您是否考虑过在kernel.terminate侦听器中进行刷新?谢谢您指出这一点。我可能需要为此创建一个EventListener,但我认为使用析构函数可以很好地实现这一点。我个人并没有这么多地使用它们,所以我认为当我有机会并且情况需要析构函数提供的那种行为时,最终尝试一下可能会很好。尽管如此,这还是有些奇怪的东西,我是说。。你怎么可能两次摧毁同一个东西?没关系,再次感谢你的建议有一些关于析构函数的老帖子被多次调用,但最近没有。通常我会说您有两个实例正在创建(可能通过_profilebar),但您表示情况并非如此。我假设这只发生在生产模式中。