Слухач доктрин проти абонента


77

Я працюю у фреймворці Symfony2 і думаю, коли б користуватися підписником Doctrine проти слухача. Документація доктрини для слухачів дуже чітка, проте передплатники досить закриті. Запис кулінарної книги Symfony подібний.


Кілька днів тому Росс Так мав доповідь про Doctrine2 на конференції DutchPHPConference. Він також розглянув події в Doctrine2, і його слайди тут: slideshare.net/rosstuck/ ... можливо, це може бути якась додаткова інформація / допомога для вас.
Кіс Шеперс

Вам дійсно не потрібні слухачі у власному коді. Див. Ніколи не використовуй слухачів для отримання більш детальної відповіді
Томаш Вотруба,

Відповіді:


90

З моєї точки зору, є лише одна велика відмінність:

  • Слухач реєструється із зазначенням подій, на яких він слухає.
  • Абонент має метод, який повідомляє диспетчеру, які події він слухає

Це може здатися не великою різницею, але якщо ви задумаєтесь, то бувають випадки, коли ви хочете використовувати один над іншим:

  • Ви можете призначити одного слухача для багатьох диспетчерів з різними подіями, оскільки вони встановлюються під час реєстрації. Потрібно лише переконатися, що кожен метод знаходиться на місці в слухачі
  • Ви можете змінити події, на які зареєстрований абонент під час виконання, і навіть після реєстрації абонента, змінивши повернене значення getSubscribedEvents(Подумайте про час, коли ви слухаєте дуже галасливу подію, і ви хочете виконати щось лише один раз)

Можуть бути й інші відмінності, про які я не знаю!


19
Отже, в двох словах, абонент - це слухач, де список спостережуваних подій можна змінювати? В getSubscribedEventsЯ б тоді повертати масив, що - щось на зразок array(Events::prePersist, Events::postUpdate)я думаю?
nurikabe


посилання в дописі @Sgoettschkes порушено, поточним начебто має бути doctrine-project.org/projects/doctrine-orm/en/latest/reference/…
c33,

10

Не знаю, чи це робиться випадково чи навмисно .. Але передплатники мають вищий пріоритет, ніж слухачі - https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass .php # L73-L98

З боку доктрини, йому байдуже, що це (слухач або передплатник), врешті-решт обоє реєструються як слухачі - https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/EventManager.php # L137-L140

Це те, що я помітив.


6

Вам слід використовувати абонента подій, коли ви хочете мати справу з кількома подіями в одному класі, наприклад, у цій статті сторінки документа Symfony2, можна помітити, що прослуховувач подій може керувати лише однією подією, але, скажімо, ви хочете мати справу з кількома подіями для однієї сутності, prePersist, preUpdate, postPersist тощо ... якщо ви використовуєте прослуховувач подій, вам доведеться кодувати кілька прослуховувачів подій, по одному для кожної події, але якщо ви йдете з передплатником подій, вам просто потрібно закодувати один клас підписчиком події, подивіться, що за допомогою абонента події ви можете керувати кількома подіями в одному класі, ну ось як я його використовую, я надаю перевагу для кодування, орієнтованого на те, що потрібно модельному бізнесу, може бути використаний один приклад цього: ви хочете обробляти кілька глобальних подій життєвого циклу лише для групи ваших сутностей, для цього ви можете кодувати батьківський клас і визначити в ньому ці глобальні методи, потім змусіть ваші сутності успадкувати цей клас, а пізніше під час підписки на подію ви підпишетеся на кожну подію, яку хочете, prePersist,preUpdate, postPersist тощо ..., а потім попросіть цей батьківський клас і виконайте ці глобальні методи.


3
Можливо, я вас неправильно зрозумів, але на моєму досвіді слухач може керувати кількома подіями, наприклад, один слухач може визначати дії для prePersist, preUpdate, onFlush тощо
Чадвік Мейер,

@ChadwickMeyer, я повторюю, що "Цей слухач може слухати одну або кілька подій і отримує повідомлення кожного разу, коли ці події надсилаються". прямо з документів
Dheeraj

3

І те, і інше дозволяє виконати щось за певної події до / після збереження тощо.

Однак слухачі дозволяють вам виконувати лише поведінку, інкапсульовану в межах Вашої Сутності. Отже, прикладом може бути оновлення мітки часу "date_edited".

Якщо вам потрібно вийти за межі контексту своєї сутності, тоді вам знадобиться передплатник. Хорошим прикладом може бути виклик зовнішнього API, або якщо вам потрібно використовувати / перевірити дані, які не мають безпосереднього відношення до вашої сутності.


5
Можливо, я не розумію, але це звучить як різниця між зворотним викликом життєвого циклу та слухачем подій? Я намагаюся визначити, коли я можу використовувати (висловлюючись Symfony2) a doctrine.event_subscriberна відміну від doctrine.event_listener.
нурікабе

3

Ще одна важлива річ: передплатники подій на доктрину не дозволяють встановлювати пріоритет.

Детальніше з цього питання читайте тут


Лампочка триває. Дякую!
nurikabe

2

Ось що про це говорить документ у 4.1. Оскільки це застосовується у всьому світі до подій, я вважаю, що це також стосується і Доктрини (не впевнений на 100%).

Слухачі або передплатники

Слухачі та абоненти можуть бути використані в одному додатку нечітко. Рішення про використання будь-якого з них, як правило, залежить від особистого смаку. Однак у кожного з них є кілька незначних переваг:

  • Підписників легше використовувати повторно, оскільки знання про події зберігається в класі, а не у визначенні послуги. Ось чому Symfony внутрішньо використовує передплатників;
  • Слухачі є більш гнучкими, оскільки набори можуть умовно вмикати або вимикати кожен із них залежно від певного значення конфігурації.

http://symfony.com/doc/master/event_dispatcher.html#listeners-or-subscribers


0

З документації:

Найпоширеніший спосіб прослуховування події - це реєстрація слухача події у диспетчера. Цей слухач може прослухати одну або кілька подій і отримує повідомлення кожного разу, коли ці події надсилаються.

Іншим способом прослуховування подій є абонент події. Абонент події - це клас PHP, який може точно вказати диспетчеру, на які події йому слід підписатися. Він реалізує інтерфейс EventSubscriberInterface, який вимагає єдиного статичного методу, який називається getSubscribedEvents ().

Дивіться приклад тут:

https://symfony.com/doc/3.3/components/event_dispatcher.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.