在插件管理器Zend \ Mvc \ Controller \ PluginManager中找不到名为“getServiceLocator”的插件

时间:2016-09-01 19:50:31

标签: php doctrine-orm zend-framework2

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

const target = document.getElementById('draggable');
const mouseup$ = Observable.fromEvent(document, 'mouseup');
const mousedown$ = Observable.fromEvent(target, 'mousedown');
const mousemove$ = Observable.fromEvent(document, 'mousemove');

const move$ = mousedown$
  .switchMap(md => {
    md.target.style.backgroundColor = 'yellow';
    const {offsetX: startX, offsetY: startY} = md;
    const mm$ = mousemove$
      .map(mm => {
        mm.preventDefault();
        return {
          left: mm.clientX - startX,
          top: mm.clientY - startY
        };
      })
      .takeUntil(mouseup$);

    // Can the next line be avoided? 
    mm$.subscribe(null, null, () => {
      md.target.style.backgroundColor = 'purple';
    });

    return mm$;
  });

move$.subscribe((pos) => {
    target.style.top = pos.top + 'px';
    target.style.left = pos.left + 'px';
});

当我跑步时,它会返回以下错误::

  

在插件管理器Zend \ Mvc \ Controller \ PluginManager中找不到名为“getServiceLocator”的插件

此外,还有一个信息:

  

的Zend \的ServiceManager \异常\ ServiceNotFoundException的

文件:

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]);
    }
}

据我所知,问题源于C:\xampp\htdocs\Curso de ZF2\vendor\zendframework\zend-servicemanager\src\AbstractPluginManager.php:133 已从Zend Framework 2的最新版本中删除的事实。但是,我不知道如何解决这个问题,以便我可以继续测试。有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:0)

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

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

PHP Deprecated: You are retrieving the service locator from within the class ZFTool\Controller\ModuleController

在上面的示例中,$db = $this->getServiceLocator()->get('Db\ApplicationAdapter');作为构造函数参数传递,因此它将立即可供Controller使用。因此,以类似的方式,您应该为IndexController创建一个Factory,它应该通过构造函数注入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'));
    }
}

只要相应地配置了所有内容,您就可以将Factory类放在任何位置。在这个例子中,我把它放在/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

非常重要:您的文件可能会有类似的内容,但使用“invokes”作为数组键。请注意,您将使用工厂作为键名(因为您声明了一个控制器工厂),而不是“invokes”,这是针对没有依赖关系的类或常规控制器。

我还建议研究这个Migration guide for Zend Framework 3,它有很多可能有用的重要信息。

至于你所关注的课程,我建议你将PHP降级为兼容版本(如果你正在使用作曲家,那么非常容易),或者尝试在网上找到另一个最新的课程或教程。 ZF2在不同版本之间发生了显着变化,这可能不是你会发现的唯一错误,你会感到非常困惑而不是学习。如果这对您有用,请告诉我。