[Из песочницы] Краткий экскурс по основным моментам Zend Framework
С россыпью конфигов… Предмет любви нашего ЯП, обладающий хорошим MVC, благодаря чему Zend Framework — самый лучший фреймворк на PHP. Это просто фреймворк, или этот фреймворк олицетворяет собой гордость PHP-сообщества — его трудолюбивых разработчиков, так сказать, ключевой ингредиент?
Здесь вы не найдёте ответа на этот вопрос, зато узнаете про ServiceManager и ModuleManager.
Предупреждение
- Данный материал основан на том, что я искал по Zend Framework 2, кое-где фигурируют даже упоминания по версии 1.*. Не думаю, что это станет проблемой при сопоставлении с другими версиями, так как рассматриваются фундаментальные моменты и вряд ли они глобально изменятся.
- В рассуждениях и переводах (а также в пункте 1) могут оказаться грубые ошибки, как мои, так и первоисточников. На всё будут даны ссылки, а собственное творчество будет с примечанием [моё].
- Ориентировано на тех, кто погуглил и, как я, запутался. Тут не будет разворачивания блогов, пояснений и интерактива. Но будет две картинки и кошечка.
Содержание
- Термины
- Устройство фреймворка
- Общая структура и связи
- Плагины
- Визуализация
- Связи
- Схематичное представление
- От автора
- Полезные ссылки
- Бонус
Термины
Источник, немного [моё].
- Приложение — конечный продукт, сайт;
- Модуль — функционально завершенный "блок" приложения, код которого может состоять из моделей, представлений, контроллеров. Модуль расширяет функциональные возможности веб-приложения и может функционировать лишь "внутри" него; Модули регистрируются в
application.config.php
в секцииmodules
- ModuleManager — контейнер для манипуляций модулями;
- Сервис — "механизм" в модуле, для манипуляций между моделями, контроллерами, видами, прочее; Сервисы регистрируются в
module.config.php
в секцииservice_manager
. - ServiceManager — контейнер для манипуляций сервисами.
- ControllerManager — работает с сервисами и фабриками для загрузки контроллеров (
\Zend\ServiceManager\AbstractFactoryInterface
или\Zend\ServiceManager\ServiceManager
). дока - EventManager — компонент, который агрегирует обработчики событий (Listener) для одного и более именованных событий (Event), а также инициирует обработку этих событий.
- Плагин — класс, который некоторым образом расширяет функциональность всех контроллеров.
Устройство фреймворка
Общая структура и связи
Источник
ServiceManagerConfig
получает конфигурацию из config/application.config.php
(или какой-либо другой конфиг приложения, который передаётся в Application
при его создании). Когда создается Zend\Mvc\Application
, объект Zend\ServiceManager\ServiceManager
создается и настраивается через Zend\Mvc\Service\ServiceManagerConfig
. Из всех сервисов и фабрик, представленных в пространстве имен Zend\Mvc\Service
, ServiceManagerConfig
является ответственным только за три: SharedEventManager
, EventManager
и ModuleManager
.
В этот момент ModuleManager
через ServiceManager
конфигурирует сервисы и фабрики, предоставляемые в Zend\Mvc\Service\ServiceListenerFactory
. После этого Application
извлекает ModuleManager
. Такой подход позволяет максимально упростить конфигурацию основного приложения и предоставить разработчику возможность конфигурировать различные части системы MVC из модулей, переопределяя любую конфигурацию по умолчанию в сервисах этих MVC.
Это, пожалуй, самая сложная фабрика в стеке MVC. ModuleManager
, выражен в Zend\Mvc\Service\ModuleManagerFactory
. ModuleManager
ожидает, что сервис ApplicationConfig
внедрён (Di) с ключами module_listener_options
и modules
.
Затем проверяет, существует ли сервис с именем ServiceListener
, если нет, то использует фабрику с именем Zend\Mvc\Service\ServiceListenerFactory
. Он создает экземпляр Zend\ModuleManager\Listener\DefaultListenerAggregate
, используя извлеченные module_listener_options
. В ServiceListener
будет добавлено множество сервисов слушателей, таких, как слушатели методов getServiceConfig
, getControllerConfig
, getControllerPluginConfig
, getViewHelperConfig
модуля.
Он создает экземпляр Zend\ModuleManager\ModuleEvent
, установив параметр "ServiceManager" в объект менеджера сервисов. Затем ModuleManager
извлекает сервис EventManager
и присоединяет вышеупомянутых слушателей. Наконец, он создает экземпляр Zend\ModuleManager\ModuleManager
и внедряет EventManager
и ModuleEvent
.
[моё] Тот случай, когда кодом понятнее:
<?php namespace Zend\Mvc\Service; use Zend\ModuleManager\Listener\DefaultListenerAggregate;
use Zend\ModuleManager\Listener\ListenerOptions;
use Zend\ModuleManager\ModuleEvent;
use Zend\ModuleManager\ModuleManager;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface; class ModuleManagerFactory implements FactoryInterface
$configuration = $serviceLocator->get('ApplicationConfig'); $listenerOptions = new ListenerOptions($configuration['module_listener_options']); $defaultListeners = new DefaultListenerAggregate($listenerOptions); $serviceListener = $serviceLocator->get('ServiceListener'); $serviceListener->addServiceManager( $serviceLocator, 'service_manager', 'Zend\ModuleManager\Feature\ServiceProviderInterface', 'getServiceConfig' ); // то же самое для остальных методов модуля $events = $serviceLocator->get('EventManager'); $events->attach($defaultListeners); $events->attach($serviceListener); $moduleEvent = new ModuleEvent; $moduleEvent->setParam('ServiceManager', $serviceLocator); $moduleManager = new ModuleManager($configuration['modules'], $events); $moduleManager->setEvent($moduleEvent); return $moduleManager; }
}
Плагины
Источник
Фронт-контроллер использует брокер плагинов (plugin broker) в качестве реестра пользовательских плагинов, брокер плагинов также обеспечивает вызов методов событий в каждом плагине, зарегистрированном через фронт-контроллер. Архитектура контроллеров включает в себя систему плагинов, которая позволяет добавлять свой код, который будет вызываться при определенных событиях в процессе жизни контроллера.
Методы событий определены в абстрактном классе Zend_Controller_Plugin_Abstract
, от которого должны наследовать все пользовательские плагины
Визуализация
[моё]
- Читается сверху вниз, если не задано иное стрелками.
- Линии со стрелками указывают что во что входит.
- Тонкие линии без стрелок указывают что с чем связано.
- Толстые линии без стрелок указывают что чем управляет.
Связи
Схема
От автора
Совпадение? Внимательный читатель заметил, что статья начинается со ссылки на Тостер, где задан вопрос про различия ServiceManager и ModuleManager, и с них же начинается текст статьи. Дело в том, что Хабр стал первым местом, откуда я начал знакомство с основами фреймворка и путаницу внесла публикация, где воссоздавался блог из документации с комментариями автора статьи. Не думаю. Именно отсутствие описания ModuleManager толкнуло меня на неправильные рассуждения (что в ServiceManager регистрируются модули) и это привело к написанию данной статьи.
Полезные ссылки
Не хочу заниматься копипастой и выращивать 6 частей на одну тему, поэтому прикладываю список моих закладок по ZF с примечаниями:
Осторожно, спойлер!
Блог
В трёх статьях c Хабра
- https://habr.com/post/192522/
- Вольный перевод документации по разработке простого блога на ZendSkeletonApplication. Рассказывается о конфигах, ServiceManager (или ModuleManager, я так и не понял) и подключении сторонних библиотек.
Оригинал документации на блог
EventManager
Первичный обзор
Подробный разбор
ServiceManager
Quick start
Подробный разбор
ModuleManager
Документация
Разумеется, принимаются правки, предложения, критика и другие дозволенные правилами Хабра и действующими законодательствами РФ действия с вашей стороны. Надеюсь, краткий экскурс не слишком затянулся и был полезен.
Бонус, который мы заслужили:
Кошечка
(=^・ω・^=)