Деструктор службы Symfony вызывается несколько раз

Я уже давно играю с Symfony 4 и недавно создал расширение для одной из своих веб-страниц, которое отвечает за перевод любой строки на основе данных в базе данных. К сожалению, я столкнулся со странной проблемой, которую не могу решить. Я постараюсь записать, что происходит в хронологическом порядке, чтобы это было более понятно.

  1. DatabaseTranslateExtension регистрирует новый |translate фильтр в Twig.
  2. |translate фильтр запускает ленивая-нагруженный TranslationService быть построенным (когда это еще не построено, конечно).
  3. Там только один случай TranslationService создано (что ожидается).
  4. Конструктор предварительно загружает данные, поэтому он не вызывает базу данных каждый раз, когда происходит перевод.
  5. Фильтр вызывает translate метод, который либо переводит строку, либо (если в базе данных нет перевода) добавляет строку в переменную экземпляра, давайте назовем ее stringsToTranslate, который является типом массива (String[]).
  6. После перевода всех строк служба деструктор должен быть вызван, который очищает stringsToTranslate массив в базу данных.

Недавно я понял, что у меня есть много дубликатов в базе данных, поэтому я попытался отладить приложение и посмотреть, что происходит. Так или иначе, я понятия не имел, что это возможно, деструктор службы вызывается дважды, ни разу. Я почти уверен, что Symfony как-то связан с этим (это может быть из-за отложенной загрузки) или с некоторыми классами, которые он создает. Мне интересно, есть ли что-нибудь, о чем вы можете подумать, что заставило бы деструктор быть вызванным дважды (да, это точно такой же экземпляр класса). Заранее спасибо.


Я обнаружил код во встроенном приложении и обнаружил созданную для моего сервиса оболочку, которая вызывает деструктор, вот код:

public function __destruct()
{
$this->initializer2b670 || $this->valueHolder90d49->__destruct();
}

Что интересно, что это __destruct также вызывается дважды. Кажется, что это потому, что там также создан класс Reflection и оба класса вызывают destruct.
Я бросил __destructorтело Первая оценка была falseЭто означает, что нужно вызвать разрушение на valueHolder класс, а затем он вызывается еще раз, что оценивается true (это, вероятно, называется также уничтожить). Weird.

1

Решение

Если у кого-то есть подобная проблема, используйте KernelEvents::RESPONSE или же KernelEvents::TERMINATE вместо __destructor,

  • KernelEvent::RESPONSE срабатывает до отправки ответа.
  • KernelEvent::TERMINATE срабатывает после отправки ответа.

Подробнее о жизненном цикле / событиях Symfony можно узнать Вот.


Для тех, кто интересуется __destruct вызывается несколько раз, вероятно, из-за класса отражения, созданного поверх оболочки. Нормальный экземпляр класса и отраженный экземпляр класса разрушены, я, вероятно, это вызывает его пару раз.

1

Другие решения

Других решений пока нет …