Я занимаюсь разработкой системы 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;
}
Я все перепробовал, кто-то знает, что мне делать?
Вам не нужно ничего делать, еще. При обновлении до 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, а также этот блог обсуждает, почему внедрение службы с помощью локатора службы является антишаблоном.
Вы можете создать плагин контроллера оказание услуг() (но это плохая практика, предпочитаю 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);
}
}