Шаблон проектирования для внедрения плагинов в приложениях PHP

Существует ли консенсус относительно того, как плагины должны быть реализованы в приложении PHP?

Я просмотрел шаблон наблюдателя, который близок, это просто система уведомлений и не позволяет коду расширять приложение напрямую. В настоящее время я использую простые системы крюков, с которыми я столкнулся:

public function registerHook($hookName, array $params = array()) { $this->hooks[] = $hookName; foreach ( $this->plugins as $pluginName => $hooks ) { if ( in_array($hookName, $hooks) ) { $plugin = new $pluginName($this, $this->view, $this->controller); $plugin->{$hookName}($params); } } } 

Это хорошо работает для моих целей, но мне любопытно, есть ли образец дизайна, который был проверен и проверен много раз, и я просто повторно изобретаю колесо.

Консенсуса нет, как в смысле Серебряной пули. Для установленных шаблонов у вас есть несколько вариантов

  • Тема / Наблюдатель ,
  • Сигнальный слот ,
  • Диспетчер событий или
  • Трубы и фильтры

назвать несколько.

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

Я считаю, что диспетчер событий – это хороший и чистый способ реализовать плагины или любое расширение. Диспетчер событий – это реализация шаблона Observer и используется в Symfony, Symfony2 и Zend Framework 2 (бета).

Просматривая любой из этих источников на github, вы получите какое-то интересное чтение. Хотя интересную информацию можно найти здесь:

http://components.symfony-project.org/event-dispatcher/trunk/book/02-Recipes

Я написал класс Events и Hooks несколько лет назад для проекта, я отправлю его здесь, если найду его.

Взгляните на структуру Yii. Yii в значительной степени полагается на события, которые намного чище, чем крючки, действия и т. Д. Используя события, вы можете разрешить различным частям системы разговаривать друг с другом объектно-ориентированным образом.

Zend Framework использует методы dispatchLoopStartup () и dispatchLoopShutdown () как методы класса. Каждый плагин является классом, который реализует вышеупомянутые методы.

ZF руководство пользователя

То, как вы это сделали, с крючками – это также то, как я это реализую.

Однако самая большая проблема с вашим образцом заключается в том, что ваша функция создает экземпляр плагина. Почему бы не передать экземпляр плагина?

То, как я это сделал, заключается в том, что сначала создается экземпляр плагина, и он сам регистрирует свои крючки.

Ну, есть ссылка на проект под названием jin-plugin прямо в статье Википедии о концепции плагина . Я тоже впервые вижу эту структуру, но, возможно, вы можете сразу ее использовать.

Кроме того, вы должны действительно google для таких вещей, как «Plugin Pattern», на первой странице есть всего две ссылки: шаблон Plug-in, шаблон расширяемости (wikipedia) .

Если это действительно шаблон, он должен быть агностическим, поэтому вы можете безопасно использовать любое существующее решение с любого языка и преобразовать его в PHP.

PS Спасибо за вопрос, во всяком случае, вы действительно подняли мой интерес к этой теме. 😉