Краткий экскурс по основным моментам Zend Framework

в 17:52, , рубрики: php, Zend Framework, zend framework 2, основы

Это просто фреймворк, или этот фреймворк олицетворяет собой гордость PHP-сообщества — его трудолюбивых разработчиков, так сказать, ключевой ингредиент? С россыпью конфигов… Предмет любви нашего ЯП, обладающий хорошим MVC, благодаря чему Zend Framework — самый лучший фреймворк на PHP.

Здесь вы не найдёте ответа на этот вопрос, зато узнаете про ServiceManager и ModuleManager.

Бегите, глупцы!

Предупреждение

  1. Данный материал основан на том, что я искал по Zend Framework 2, кое-где фигурируют даже упоминания по версии 1.*. Не думаю, что это станет проблемой при сопоставлении с другими версиями, так как рассматриваются фундаментальные моменты и вряд ли они глобально изменятся.
  2. В рассуждениях и переводах (а также в пункте 1) могут оказаться грубые ошибки, как мои, так и первоисточников. На всё будут даны ссылки, а собственное творчество будет с примечанием [моё].
  3. Ориентировано на тех, кто погуглил и, как я, запутался. Тут не будет разворачивания блогов, пояснений и интерактива. Но будет две картинки и кошечка.

Содержание

  • Термины
  • Устройство фреймворка
    • Общая структура и связи
    • Плагины
  • Визуализация
    • Связи
    • Схематичное представление
  • От автора
    • Полезные ссылки
  • Бонус

Термины

Источник, немного [моё].

  • Приложение — конечный продукт, сайт;
  • Модуль — функционально завершенный "блок" приложения, код которого может состоять из моделей, представлений, контроллеров. Модуль расширяет функциональные возможности веб-приложения и может функционировать лишь "внутри" него; Модули регистрируются в application.config.php в секции modules
  • ModuleManager — контейнер для манипуляций модулями;
  • Сервис — "механизм" в модуле, для манипуляций между моделями, контроллерами, видами, прочее; Сервисы регистрируются в module.config.php в секции service_manager.
  • ServiceManager — контейнер для манипуляций сервисами.
  • ControllerManager — работает с сервисами и фабриками для загрузки контроллеров (ZendServiceManagerAbstractFactoryInterface или ZendServiceManagerServiceManager). дока
  • EventManager — компонент, который агрегирует обработчики событий (Listener) для одного и более именованных событий (Event), а также инициирует обработку этих событий.
  • Плагин — класс, который некоторым образом расширяет функциональность всех контроллеров.

Устройство фреймворка

Общая структура и связи

Источник

Когда создается ZendMvcApplication, объект ZendServiceManagerServiceManager создается и настраивается через ZendMvcServiceServiceManagerConfig. ServiceManagerConfig получает конфигурацию из config/application.config.php(или какой-либо другой конфиг приложения, который передаётся в Application при его создании). Из всех сервисов и фабрик, представленных в пространстве имен ZendMvcService, ServiceManagerConfig является ответственным только за три: SharedEventManager, EventManager и ModuleManager.

После этого Application извлекает ModuleManager. В этот момент ModuleManager через ServiceManager конфигурирует сервисы и фабрики, предоставляемые в ZendMvcServiceServiceListenerFactory. Такой подход позволяет максимально упростить конфигурацию основного приложения и предоставить разработчику возможность конфигурировать различные части системы MVC из модулей, переопределяя любую конфигурацию по умолчанию в сервисах этих MVC.


ModuleManager, выражен в ZendMvcServiceModuleManagerFactory. Это, пожалуй, самая сложная фабрика в стеке MVC. ModuleManager ожидает, что сервис ApplicationConfig внедрён (Di) с ключами module_listener_options и modules.

Он создает экземпляр ZendModuleManagerListenerDefaultListenerAggregate, используя извлеченные module_listener_options. Затем проверяет, существует ли сервис с именем ServiceListener, если нет, то использует фабрику с именем ZendMvcServiceServiceListenerFactory. В ServiceListener будет добавлено множество сервисов слушателей, таких, как слушатели методов getServiceConfig, getControllerConfig, getControllerPluginConfig, getViewHelperConfig модуля.

Затем ModuleManager извлекает сервис EventManager и присоединяет вышеупомянутых слушателей. Он создает экземпляр ZendModuleManagerModuleEvent, установив параметр "ServiceManager" в объект менеджера сервисов. Наконец, он создает экземпляр ZendModuleManagerModuleManager и внедряет EventManager и ModuleEvent.

[моё] Тот случай, когда кодом понятнее:

<?php

namespace ZendMvcService;

use ZendModuleManagerListenerDefaultListenerAggregate;
use ZendModuleManagerListenerListenerOptions;
use ZendModuleManagerModuleEvent;
use ZendModuleManagerModuleManager;
use ZendServiceManagerFactoryInterface;
use ZendServiceManagerServiceLocatorInterface;

class ModuleManagerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        if (!$serviceLocator->has('ServiceListener')) {
            $serviceLocator->setFactory('ServiceListener', 'ZendMvcServiceServiceListenerFactory');
        }

        $configuration    = $serviceLocator->get('ApplicationConfig');
        $listenerOptions  = new ListenerOptions($configuration['module_listener_options']);
        $defaultListeners = new DefaultListenerAggregate($listenerOptions);
        $serviceListener  = $serviceLocator->get('ServiceListener');

        $serviceListener->addServiceManager(
            $serviceLocator,
            'service_manager',
            'ZendModuleManagerFeatureServiceProviderInterface',
            '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

Документация

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


Бонус, который мы заслужили:

Кошечка

(=^・ω・^=)

Автор: Сергей Мелодин

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js