Учебники

Zend Framework — Сервис-менеджер

Zend Framework включает в себя мощную реализацию шаблона поиска сервисов, которая называется zend-servicemanager . Zend Framework широко использует диспетчер сервисов для всех своих функций. Service Manager предоставляет высокоуровневую абстракцию для Zend Framework. Он также прекрасно интегрируется со всеми другими компонентами Zend Framework.

Установите Service Manager

Компонент Service Manager может быть установлен с помощью инструмента composer .

composer require zendframework/zend-servicemanager

пример

Во-первых, все сервисы должны быть зарегистрированы в диспетчере сервисов. Как только сервисы зарегистрированы в системе диспетчера серверов, к ним можно получить доступ в любое время с минимальными усилиями. Менеджер сервиса предоставляет множество опций для регистрации сервиса. Простой пример выглядит следующим образом —

use Zend\ServiceManager\ServiceManager; 
use Zend\ServiceManager\Factory\InvokableFactory; 
use stdClass;  
$serviceManager = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class,], 
]);

Приведенный выше код регистрирует stdClass в системе, используя опцию Factory . Теперь мы можем получить экземпляр stdClass в любое время, используя метод get () менеджера сервисов, как показано ниже.

use Zend\ServiceManager\ServiceManager;  
$object = $serviceManager->get(stdClass::class);

Метод get () разделяет извлеченный объект, и поэтому объект, возвращаемый путем многократного вызова метода get (), является одним и тем же экземпляром. Чтобы каждый раз получать новый экземпляр, менеджер сервисов предоставляет другой метод, который является методом build () .

use Zend\ServiceManager\ServiceManager;  
$a = $serviceManager->build(stdClass::class); 
$b = $serviceManager->build(stdClass::class);

Регистрация менеджера сервиса

Диспетчер служб предоставляет набор методов для регистрации компонента. Некоторые из наиболее важных методов приведены ниже.

  • Заводской метод
  • Абстрактный фабричный метод
  • Метод инициализатора
  • Метод фабрики делегатов

Мы обсудим каждый из них подробно в следующих главах.

Заводской метод

Фабрика — это любой вызываемый или любой класс, реализующий FactoryInterface (Zend \ ServiceManager \ Factory \ FactoryInterface).

FactoryInterface имеет единственный метод —

public function __invoke(ContainerInterface $container, $requestedName, array 
   $options = null)

Детали аргументов FactoryInterface следующие:

  • container (ContainerInterface) — это базовый интерфейс ServiceManager. Это дает возможность получить другие услуги.

  • запрашиваемое имя — это имя службы.

  • параметры — это дает дополнительные параметры, необходимые для службы.

container (ContainerInterface) — это базовый интерфейс ServiceManager. Это дает возможность получить другие услуги.

запрашиваемое имя — это имя службы.

параметры — это дает дополнительные параметры, необходимые для службы.

Давайте создадим простой класс, реализующий FactoryInterface, и посмотрим, как его зарегистрировать.

Тест класса — объект, который нужно получить

use stdClass;  
class Test { 
   public function __construct(stdClass $sc) { 
      // use $sc 
   } 
} 

Класс Test зависит от stdClass.

Class TestFactory — класс для инициализации тестового объекта

class TestFactory implements FactoryInterface { 
   public function __invoke(ContainerInterface $container, $requestedName, 
      array $options = null) { 
      $dep = $container->get(stdClass::class); 
      return new Test($dep); 
   } 
}

TestFactory использует контейнер для извлечения stdClass, создает экземпляр класса Test и возвращает его.

Регистрация и использование Zend Framework

Давайте теперь поймем, как зарегистрироваться и использовать Zend Framework.

serviceManager $sc = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class, 
      Test::class => TestFactory::class] 
]); 
$test = $sc->get(Test::class);

Менеджер сервисов предоставляет специальную фабрику InvokableFactory для извлечения любого класса, который не имеет зависимости. Например, stdClass можно настроить с помощью InvokableFactory, поскольку stdClass не зависит от какого-либо другого класса.

serviceManager $sc = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class] 
]);  
$stdC = $sc->get(stdClass::class); 

Другой способ получения объекта без реализации FactoryInterface или использования InvokableFactory — использование встроенного метода, как указано ниже.

$serviceManager = new ServiceManager([ 
   'factories' => [ 
      stdClass::class => InvokableFactory::class, 
      Test::class => function(ContainerInterface $container, $requestedName) { 
         $dep = $container->get(stdClass::class); 
         return new Test($dep); 
      }, 
   ], 
]);

Метод абстрактной фабрики

Иногда нам может понадобиться создать объекты, которые мы узнаем только во время выполнения. Эта ситуация может быть обработана с использованием AbstractFactoryInterface , который является производным от FactoryInterface.

AbstractFactoryInterface определяет метод для проверки, может ли объект быть создан в запрошенном экземпляре или нет. Если создание объекта возможно, он создаст объект с помощью __invokemethod из FactoryInterface и вернет его.

Подпись AbstractFactoryInterface выглядит следующим образом:

public function canCreate(ContainerInterface $container, $requestedName) 

Метод инициализатора

Метод Initializer — это специальная опция для добавления дополнительных зависимостей для уже созданных сервисов. Он реализует InitializerInterface и подпись единственного доступного метода выглядит следующим образом:

public function(ContainerInterface $container, $instance)  
function(ContainerInterface $container, $instance) { 
   if (! $instance instanceof EventManagerAwareInterface) { 
      return; 
   } 
   $instance->setEventManager($container->get(EventManager::class)); 
} 

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

Метод фабрики делегатов

Zend Framework поддерживает шаблон делегатов через DelegatorFactoryInterface . Это может быть использовано для украшения службы.

Сигнатура этой функции выглядит следующим образом —

public function __invoke(ContainerInterface $container, 
   $name, callable $callback, array $options = null 
); 

Здесь обратный вызов $ отвечает за оформление экземпляра службы.

Ленивые Услуги

Ленивый сервис — это один из тех сервисов, который не будет полностью инициализирован во время создания. Они просто ссылаются и инициализируются только тогда, когда это действительно необходимо. Одним из лучших примеров является соединение с базой данных, которое может понадобиться не во всех местах. Это дорогой ресурс, так как на его создание уходит много времени. Zend Framework предоставляет LazyServiceFactory, производный от DelegatorFactoryInterface , который может создавать ленивый сервис с помощью концепции делегатора и стороннего менеджера прокси, который называется менеджером прокси ocramius .

Менеджер плагинов

Менеджер плагинов расширяет менеджер сервисов и предоставляет дополнительные функции, такие как проверка экземпляров. Zend Framework широко использует менеджер плагинов.

Например, все службы проверки подпадают под ValidationPluginManager .

Вариант конфигурации

Диспетчер сервисов предоставляет некоторые опции для расширения возможностей диспетчера сервисов. Они являются общими, shared_by_default и псевдонимами . Как мы уже говорили ранее, извлеченные объекты по умолчанию распределяются между запрашиваемыми объектами, и мы можем использовать метод build () для получения отдельного объекта. Мы также можем использовать параметр общего доступа, чтобы указать, какой сервис будет использоваться совместно. Shared_by_default — это то же самое, что и общая функция, за исключением того, что она применяется ко всем сервисам.

$serviceManager = new ServiceManager([ 
   'factories' => [ 
      stdClass::class => InvokableFactory::class 
   ], 
   'shared' => [ 
      stdClass::class => false // will not be shared 
   ], 
   'shared_by_default' => false, // will not be shared and applies to all service 
]);

Опцию псевдонимов можно использовать для предоставления альтернативного имени зарегистрированным сервисам. Это имеет как преимущества, так и недостатки. С другой стороны, мы можем предоставить альтернативные короткие имена для услуги. Но в то же время имя может выйти из контекста и привести к ошибкам.