Устаревший: получить сервисный локатор в функциональной системе — ZF2

Я занимаюсь разработкой системы ZF2, и она работала очень хорошо, но после того, как я клонировал репозиторий на другом компьютере, появилась эта устаревшая ошибка:

Вы получаете сервисный локатор из класса Module \ Controller \ Controller. Обратите внимание, что ServiceLocatorAwareInterface устарела и будет удалена в версии 3.0 вместе с ServiceLocatorAwareInitializer. Вам нужно будет обновить ваш класс так, чтобы он принимал все зависимости при создании, либо через аргументы конструктора, либо через сеттеры, и использовал фабрику для выполнения инъекций. в /home/path/project/vendor/zendframework/zend-mvc/src/Controller/AbstractController.php в строке 258

Композитор.json:

"require": {
"php": ">=5.5",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"zendframework/zendframework": "~2.5",
"doctrine/doctrine-orm-module": "0.*",
"hounddog/doctrine-data-fixture-module": "0.0.*",
"imagine/Imagine": "~0.5.0"

Ошибка появляется, когда я получаю сервис в моих контроллерах (расширение Zend \ Mvc \ Controller \ AbstractActionController):

$this->getServiceLocator()->get("Module\Service\Service");

В ядре Zend в Zend \ Mvc \ Controller \ AbstractController это выглядит так:

public function getServiceLocator()
{
trigger_error(sprintf(
'You are retrieving the service locator from within the class %s. Please be aware that '
. 'ServiceLocatorAwareInterface is deprecated and will be removed in version 3.0, along '
. 'with the ServiceLocatorAwareInitializer. You will need to update your class to accept '
. 'all dependencies at creation, either via constructor arguments or setters, and use '
. 'a factory to perform the injections.',
get_class($this)
), E_USER_DEPRECATED);

return $this->serviceLocator;
}

До этого было только это:

public function getServiceLocator()
{
return $this->serviceLocator;
}

Я все перепробовал, кто-то знает, что мне делать?

9

Решение

Вам не нужно ничего делать, еще. При обновлении до ZF3 вам придется изменить способ класс контроллера получает свои зависимости.

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

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

namespace Module\Controller;

class Controller {
public function __construct(\Module\Service\Service $service) {
$this->service = $service;
}
}

использование $this->service где вам это нужно в методах класса.

Затем используйте фабрику контроллеров для создания вашего контроллера, вот так:

function ($controllers) {
$services = $controllers->getServiceLocator();
return new \Module\Controller\Controller($services->get('Module\Service\Service'));
}

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

10

Другие решения

Вы можете создать плагин контроллера оказание услуг() (но это плохая практика, предпочитаю FactoryInterface)

module.config.php

'controller_plugins' => [
'factories' => [
'service' => YourNamespace\Mvc\Controller\Plugin\Service\ServiceFactory::class,
],
],

YourNamespace \ Mvc \ Controller \ Plugin \ Сервис \ ServiceFactory.php

<?php

namespace YourNamespace\Mvc\Controller\Plugin\Service;

use Interop\Container\ContainerInterface;
use YourNamespace\Mvc\Controller\Plugin\Service;
use Zend\ServiceManager\Factory\FactoryInterface;

class ServiceFactory implements FactoryInterface
{
/**
* @param  ContainerInterface $container
* @param  string $requestedName
* @param  array $options
* @return Service
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$plugin = new Service();
$plugin->setServiceLocator($container);
return $plugin;
}
}

YourNamespace \ Mvc \ Controller \ Plugin \ Service.php

<?php

namespace YourNamespace\Mvc\Controller\Plugin;

use Interop\Container\ContainerInterface;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;

/**
* Plugin: $this->service();
*/
class Service extends AbstractPlugin
{
/**
* @var ContainerInterface
*/
protected $serviceLocator;

/**
* @return ContainerInterface
*/
public function getServiceLocator()
{
return $this->serviceLocator;
}

/**
* @param  ContainerInterface $serviceLocator
* @return Service
*/
public function setServiceLocator(ContainerInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
return $this;
}

/**
* @param  string $name
* @return object|bool
*/
public function __invoke($name = null)
{
$sl = $this->getServiceLocator();
if (!$name) {
return $sl;
}
if (!$sl->has($name)) {
return false;
}
return $sl->get($name);
}
}
1