Деструктор службы Symfony вызывается несколько раз - PullRequest
0 голосов
/ 25 июня 2018

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

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

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


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

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

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

1 Ответ

0 голосов
/ 29 июня 2018

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

  • KernelEvent::RESPONSE перед отправкой ответа.
  • KernelEvent::TERMINATE запускается после отправки ответа.

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


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

...