Deprecated: Retrieve service locator in functional system - ZF2

后端 未结 2 391
余生分开走
余生分开走 2021-01-02 09:03

I\'m developing a ZF2 system and it was working very well, but after I clone the repository in other computer this deprecated error has appeared:

You

相关标签:
2条回答
  • 2021-01-02 09:20

    You can create a controller plugin service() (but it's a bad practice, prefer FactoryInterface)

    module.config.php

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

    YourNamespace\Mvc\Controller\Plugin\Service\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);
        }
    }
    
    0 讨论(0)
  • 2021-01-02 09:32

    You don't have to do anything, yet. When you upgrade to ZF3, then you will have to change how your controller class receives its dependencies.

    ZF2 supports two dependency injection patterns: by service locator and by constructor. ZF3 removes "by service location" and requires "by constructor". All this does, effectively, is change how dependencies resolve, moving the resolution from "just in time" to "at construction".

    Instead of being able to get a service from anywhere, you instead receive them at construction. Update your code along the following lines:

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

    Use $this->service where you need it in the class's methods.

    Then use a controller factory to create your controller, like so:

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

    The change is discussed in Issue 5168, and this blog post discusses why service injection with a service locator is an anti-pattern.

    0 讨论(0)
提交回复
热议问题