За последние 24 часа нас посетили 58186 программистов и 1683 робота. Сейчас ищет 1321 программист ...

Связь модулей, события и наблюдатели

Тема в разделе "PHP для новичков", создана пользователем Dedov_Evgeniy, 7 мар 2018.

  1. Dedov_Evgeniy

    Dedov_Evgeniy Активный пользователь

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Здравствуйте.
    Вот объясните мне...
    У нас сейчас в системе есть 10-15 модулей. MVC, слабая связанность, отдельно модели, отдельно вьюхи.. Всё работает.
    Но пришли в к тому что нужна более большая гибкость и расширяемость.
    Знакомы почти со всеми основными патэрнами проектирования, с их тех. реализацией, но на первом этапе много непонятного ИМЕННО в конкретной реализации.

    Вот например Событие - наблюдатель.
    Объясните "на пальцах"
    Есть класс который может подписывать и отписывать наблюдателей, а так же создавать события.

    Например есть два модуля "Каталог товаров" - инициатор какого то события
    И например модуль "Витрины"

    Оба модуля лежат каждый в своей директории и ни как не пересекаются и не знают друг о друге.

    Вот в Каталоге произошло событие "Добавили товар" ($this->event->dispatch('catalog_new_product');) на которое подписана Витрина (
    $this->event->addListener('catalog_new_product', function () {
    echo 'Добавили товар...';
    });
    ). Ну и что - витрина так же спокойно лежит в своей папке и так же ни чего не знает, что с того что она подписана...

    Как дальше то их связать. Что первое приходит на ум это нужно иметь в системе какой то перечень активных модулей которые могут подписываться и инициировать события и от этого отталкиваться.
    То есть перебирать эти модули и смотреть есть ли подписчики или инициаторы событий.

    Надеюсь я более менее понятно объяснил суть недопонимания.
     
  2. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Прослушивание и подписка на события это в основном в асинхронном js, в пхп не нужны активные модули и данные должны связываться в базе.
     
  3. Dedov_Evgeniy

    Dedov_Evgeniy Активный пользователь

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Вы не поняли сути вопроса...
    Вообще я про это... http://boliev.ru/potencier_part9/
     
  4. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Ну, в целом так оно и должно быть. Посмотрите на реализацию в laravel: http://laravel.su/docs/5.4/events

    Если кратко, каждый пакет имеет свой ServiceProvider, который добавляется в конфиг. При старте все они запускаются и регистрируют все что необходимо. Так же есть отдельный EventServiceProvider, для регистрации событий / слушателей приложения. В результате имеем наглядную картину на уровне приложения и возможность расширения сторонними пакетами.
     
  5. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Смотри. Есть у нас событие "создания заказа": тупо создаются записи в БД и затем происходит disptach('CreateOrder'). Дальше, модуль Notifications ловит это событие и шлет смсину и письмо на почту с манагерским ушевтиранием, после чего то же событие ловит Broadcasting и пинает эту запись в сторону фронта, в результате чего новый заказ появляется в кабинете манагера по средством магии соккетов. Удобно же )
     
    keren нравится это.
  6. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    Ну чтоб она была подписана, должен хотя бы запуститься модуль, который её подписывает. Ну и с событием передаётся какая-то информация, которую инициатор считает важной для того, чтобы возможно было событие обработать.
     
  7. Dedov_Evgeniy

    Dedov_Evgeniy Активный пользователь

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Здравствуйте. Вот, пришлось вернуться к этой теме, потому что проблема встала очень остро. Просьба ещё раз объяснить правильно ля я понимаю весь алгоритм действий работы патерна Observer (наблюдатель) или система событий в проекте. Именно как реализовано в грамотных фреймворках Symfony, Laravel. Просьба не тыкать "посмотри там" как реализовано, я всё это читал и довольно много, только чуть не хватает информации что бы картинка в голове сложилась.
    В общем, о сути реализации всё ясно, не понятно одно, всё как написано в первом моём сообщении.
    У меня всего 2-3 вопроса, я очень уважаю этот форум и людей которые здесь пишут, много здесь полезной информации прочитал, поэтому прошу "на пальца" объяснить правильно ля я понимаю реализацию.

    В системе есть объект с помощью которого я могу сгенериравать событие и вместе с ним передать всем подписчикам всю необходимую информацию (не важно, это может быть простой массив, объект, просто переменная...) Не понятно вот что, один модуль сгенерировал событие, как другой то класс об этом узнает?

    То есть как я понял, как минимум должен быть глобальный (объект, конфиг, не важно...) в который заносим всех подписчиков. Например:
    PHP:
    1. protected $listen = [
    2.    // Событие, ключ
    3.     'App\Events\OrderShipped' => [
    4.         // Слушатель, namespace / класс / метод
    5.         'App\Listeners\SendShipmentNotification',
    6.     ],
    7. ];
    У каждого модуля создаём специальный класс слушатель событий и в нем методы необходимые.

    После возникновении события мы пробегаемся по всем событиям в глобальном объекте, создаём нужный экземпляр класса, запускаем метод - слушатель события + туда передаём инфу дополнительную.

    1 вопрос правильно я понял?
    2 вопрос, а если в системе будет 1000 событий и обработчиков, это подключение такого кол-ва файлов + создание такого количества объектов, это нормально?

    Просьба, объяснить.
     
  8. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    Или глобальный конфиг событий, или какой-нибудь инициализирующий код, который у модуля всегда запускается и подписывает на события. К примеру, в Yii2, где есть понятие модуля на уровне фреймворка, если модуль хочет слушать события, то его надо указать в разделе bootstrap конфига приложения. В пакете Laravel Modules, который добавляет модули к laravel, у каждого модуля есть Service Provider, который будет запускаться всегда и в нём можно подписывать на события.
    Нормально. Хотя, если злоупотреблять событиями, логика кода становится труднопрослеживаемой. Во всём нужно меру знать
     
    #8 mkramer, 14 фев 2019
    Последнее редактирование: 14 фев 2019
  9. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    Тот объект который сгенерировал событие отправляет информацию об этом всем зарегистрированным наблюдателям (слушателям).
    Евгений, вы подачу данного вопроса от Зандстры читали? Из того , что у меня есть могу посоветовать ещё одну книгу, но у меня она 2006 года, по идее должны быть новее редакции. Там тоже хорошо описан этот вопрос. "РНР5 для профессионалов"
     
  10. Dedov_Evgeniy

    Dedov_Evgeniy Активный пользователь

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    Я написал всё в простом и абстрактном виде, те кто понял и хочет помочь, те ответят. PHP я отлично знаю, и вопрос вообще был в другом, если Вам нехрен делать - лучше не писать всякую чушь про то что "Я всё знаю, а Вы идите туда и читайте там".... Спасибо
     
  11. Dedov_Evgeniy

    Dedov_Evgeniy Активный пользователь

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    mkramer,
    Спасибо, за ответ. Просто у нас сейчас проект стал сильно разрастаться, и вопрос грамотного кода и патерны стоит на первом месте, а вообще не хочется (пока..) подключать или переходить на удобные фреймфорки и городить потом 10 этажные уровни кэша, что бы это всё быстро работало, хотя удобство и быстрота - тоже рулит... Ну пока нет надобности...
     
  12. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    @Dedov_Evgeniy, а что, у вас такой гружёный проект, что фреймворк его убъёт? К примеру, yii2 очень быстрый фреймворк. Laravel конечно потяжелее, но вот тут @romach часто рекламирует его сочетание с swoole - получится сверхбыстрое приложение, поскольку swoole учит php-приложения висеть в памяти, как на node js, а не грузиться с самого начала после каждого запроса
     
  13. Dedov_Evgeniy

    Dedov_Evgeniy Активный пользователь

    С нами с:
    14 май 2015
    Сообщения:
    58
    Симпатии:
    1
    @mkramer
    Изначально когда проект был как отдельная копия для каждого клиента, то нагрузки вообще не было. Сейчас хотим сделать 1 - 2 копии между которыми будет равномерный баланс по http запросам. БД конечно у каждого своя, так проще будет вносить глобальные правки по регионам, ещё много плюсов... В этом случае нагрузка возрастает в разы, уже тестим потихоньку. Сейчас у нас приложение очень быстрое, любая стр. собирается за 0.002 - 0.006. Sql 3 максимум 9. Это когда включен кэш. Причём кэш как на уровне html так sql. В БД без надобности ничего не складываться, по принципу как в битриксе компонент со статичным html или php... Сейчас хотим потихоньку перейти на компоненты Symfony. Как то так