在插件管理器 Zend\Mvc\Controller\PluginManager 中找不到名为 "getServiceLocator" 的插件
A plugin by the name "getServiceLocator" was not found in the plugin manager Zend\Mvc\Controller\PluginManager
最近开始通过课程学习 AngularJS 和 Zend Framework 2。考虑到课程的年份,如果我记得是 2013 年,两个框架中的一些事情都发生了变化。很快,我遇到了使用以下代码片段测试与数据库的连接并使用 Doctrine 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]);
}
}
当我运行时,它returns出现以下错误::
A plugin by the name "getServiceLocator" was not found in the plugin manager Zend\Mvc\Controller\PluginManager
此外,补充一个信息:
Zend\ServiceManager\Exception\ServiceNotFoundException
文件:
C:\xampp\htdocs\Curso de ZF2\vendor\zendframework\zend-servicemanager\src\AbstractPluginManager.php:133
据我所知,问题源于 getServiceLocator()
已从最新版本的 Zend Framework 2 中删除。但是,我不知道如何解决这个问题,以便我可以继续测试。有人可以帮助我吗?
如果您已经从 composer 更新或签出 Zend Framework 3,并且如果它只是为了让您的课程 material 正常工作,您可以降级到更早的 (2.x) 版本,其中 getServiceLocator()
可用,但 已弃用 。它从 3.0 开始被删除。
更好的方法是了解如何解决它,因为无论如何您将来都必须这样做。基本上,您不应该在运行时注入依赖项,而是实际上为您的控制器注册一个工厂,然后通过构造函数传递依赖项。可能的修复在以下问题的接受答案中得到了很好的解释:
在上面的示例中,$db = $this->getServiceLocator()->get('Db\ApplicationAdapter');
作为构造函数参数传递,因此它将立即可供控制器使用。所以以类似的方式,你应该为你的 IndexController
创建一个工厂,它应该 return 它已经通过构造函数注入 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'));
}
}
您可以将您的工厂 class 放置在任何地方,只要一切都进行了相应的配置。在这个例子中,我把它放在 /Module/yourModule/src/yourModule/Controller/Factory/IndexControllerFactory.php
.
随着上面的 class 被调用,您的 $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" 作为数组键。请注意,您将使用 factories 作为键名(因为您正在声明一个控制器工厂),而不是 "invokes",后者适用于 class 没有依赖项或常规控制器。
我也建议学习这个Migration guide for Zend Framework 3,它有很多重要的信息可能会有所帮助。
至于您正在学习的那门课程,我再次建议您将 PHP 降级到兼容版本(如果您使用的是 composer,这很容易),或者尝试找到另一门最新的课程或网络教程。 ZF2 在版本之间发生了显着变化,这可能不是您会发现的唯一错误,您会感到非常困惑而不是学习。让我知道这是否适合你。
最近开始通过课程学习 AngularJS 和 Zend Framework 2。考虑到课程的年份,如果我记得是 2013 年,两个框架中的一些事情都发生了变化。很快,我遇到了使用以下代码片段测试与数据库的连接并使用 Doctrine 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]);
}
}
当我运行时,它returns出现以下错误::
A plugin by the name "getServiceLocator" was not found in the plugin manager Zend\Mvc\Controller\PluginManager
此外,补充一个信息:
Zend\ServiceManager\Exception\ServiceNotFoundException
文件:
C:\xampp\htdocs\Curso de ZF2\vendor\zendframework\zend-servicemanager\src\AbstractPluginManager.php:133
据我所知,问题源于 getServiceLocator()
已从最新版本的 Zend Framework 2 中删除。但是,我不知道如何解决这个问题,以便我可以继续测试。有人可以帮助我吗?
如果您已经从 composer 更新或签出 Zend Framework 3,并且如果它只是为了让您的课程 material 正常工作,您可以降级到更早的 (2.x) 版本,其中 getServiceLocator()
可用,但 已弃用 。它从 3.0 开始被删除。
更好的方法是了解如何解决它,因为无论如何您将来都必须这样做。基本上,您不应该在运行时注入依赖项,而是实际上为您的控制器注册一个工厂,然后通过构造函数传递依赖项。可能的修复在以下问题的接受答案中得到了很好的解释:
在上面的示例中,$db = $this->getServiceLocator()->get('Db\ApplicationAdapter');
作为构造函数参数传递,因此它将立即可供控制器使用。所以以类似的方式,你应该为你的 IndexController
创建一个工厂,它应该 return 它已经通过构造函数注入 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'));
}
}
您可以将您的工厂 class 放置在任何地方,只要一切都进行了相应的配置。在这个例子中,我把它放在 /Module/yourModule/src/yourModule/Controller/Factory/IndexControllerFactory.php
.
随着上面的 class 被调用,您的 $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" 作为数组键。请注意,您将使用 factories 作为键名(因为您正在声明一个控制器工厂),而不是 "invokes",后者适用于 class 没有依赖项或常规控制器。
我也建议学习这个Migration guide for Zend Framework 3,它有很多重要的信息可能会有所帮助。
至于您正在学习的那门课程,我再次建议您将 PHP 降级到兼容版本(如果您使用的是 composer,这很容易),或者尝试找到另一门最新的课程或网络教程。 ZF2 在版本之间发生了显着变化,这可能不是您会发现的唯一错误,您会感到非常困惑而不是学习。让我知道这是否适合你。