一个名为"getServiceLocator"在插件管理器ZendMvcControllerP


A plugin by the name "getServiceLocator" was not found in the plugin manager ZendMvcControllerPluginManager

最近开始通过课程学习AngularJS和Zend Framework 2。考虑到课程的年份,如果我记得是2013年的话,两个框架都发生了一些变化。很快,我遇到了一个问题,使用下面的代码片段来测试到数据库的连接,并使用原则2列出记录:

namespace Application'Controller;
use Zend'Mvc'Controller'AbstractActionController;
use Zend'View'Model'ViewModel;
class IndexController extends AbstractActionController {
    public function indexAction() {
        $em = $this->getServiceLocator()->get('Doctrine'ORM'EntityManager');
        $repo = $em->getRepository('Entity'Categoria');
        $categorias = $repo->findAll();
        return new ViewModel(['categories'=>$categorias]);
    }
}

当我运行时,它返回以下错误::

在插件管理器Zend'Mvc'Controller'PluginManager中找不到getServiceLocator插件

此外,附加信息:

Zend ' ServiceManager '例外' ServiceNotFoundException

文件:

C:'xampp'htdocs'Curso de ZF2'vendor'zendframework'zend-servicemanager'src'AbstractPluginManager.php:133

据我所知,这个问题源于getServiceLocator()已经从Zend Framework 2的最新版本中删除了。但是,我不知道如何解决这个问题,以便我可以继续测试。有人能帮我吗?

如果您已经从composer更新或检查了Zend Framework 3,并且如果它只是为了使您的课程材料工作,您可以降级到较早的(2.x)版本,其中getServiceLocator()可用,但已弃用。从3.0开始删除。

更好的方法是了解如何绕过它,因为无论如何,您将来都必须这样做。基本上,你不应该在运行时中间注入依赖,而应该为你的控制器注册一个工厂,然后通过构造函数传递依赖。在以下问题的可接受答案中很好地解释了可能的修复:

PHP已弃用:您正在从类ZFTool'Controller'ModuleController中检索服务定位器

在上面的例子中,$db = $this->getServiceLocator()->get('Db'ApplicationAdapter');作为构造函数参数传递,因此它将立即对控制器可用。因此,以类似的方式,您应该为您的IndexController创建一个工厂,它应该与已经通过构造函数注入的Doctrine'ORM'EntityManager一起返回(记住将"yourModule"替换为您的实际模块名称):

namespace yourModule'Controller'Factory;
use Interop'Container'ContainerInterface;
use Zend'ServiceManager'Factory'FactoryInterface;
use yourModule'Controller'IndexController;
class IndexControllerFactory implements FactoryInterface {
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null) {
        return new IndexController($container->get('Doctrine'ORM'EntityManager'));
    }
}

你可以把你的工厂类放在任何地方,只要一切都是相应的配置。在这个例子中,我把它放在/Module/yourModule/src/yourModule/Controller/Factory/IndexControllerFactory.php中。

在调用了上面的类之后,您的$em变量将被填充,并且可以从控制器中的任何地方调用(注意新属性$em及其用法:$this->em):
class IndexController extends AbstractActionController {
    protected $em;
    public function __construct(EntityManager $em) {
        $this->em = $em;
    }
    public function indexAction() {
        $repo = $this->em->getRepository('Entity'Categoria');
        $categorias = $repo->findAll();
        return new ViewModel(['categories'=>$categorias]);
    }
    ...
}

现在,在你的模块的module.config.php中注册你的新工厂,我们完成了:

<?php
return [
    // ... other stuff
    // ...
    'controllers' => [
        'factories' => [  
            'yourModule'Controller'Index' => 'yourModule'Controller'Factory'IndexControllerFactory',
            ],
    ],
    // etc...
]; 
// end of file

非常重要:您的文件可能有类似的内容,但使用" invoked "作为数组键。请注意,您将使用factories作为键名(因为您声明的是控制器工厂),而不是"invoke",后者适用于没有依赖关系的类或常规控制器。

我还建议学习这个Zend Framework 3的迁移指南,它有很多重要的信息可能会有所帮助。

对于你正在学习的课程,我再次建议你将PHP降级到兼容的版本(如果你正在使用composer,这很容易),或者尝试在网上找到另一个最新的课程或教程。《ZF2》在不同版本间发生了很大的变化,你可能会发现这并不是唯一的错误,你会感到非常困惑,而不是从中吸取教训。让我知道这是否适合你。