最近开始通过课程学习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的最新版本中删除的事实。但是,我不知道如何解决这个问题,以便我可以继续测试。有人可以帮帮我吗?
答案 0 :(得分:0)
如果您已经从作曲家更新或签出了Zend Framework 3,并且只是为了使您的课程材料正常工作,您可以降级到早期的(2.x)版本,其中getServiceLocator()
可用,但弃用。它已从3.0开始删除。
更好的方法是了解如何解决它,因为无论如何你将来必须这样做。基本上,您不应该在运行时中间注入依赖项,而是实际为您的控制器注册一个工厂,然后通过构造函数传递依赖项。可接受的修复在以下问题的接受答案中得到了解释:
在上面的示例中,$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在不同版本之间发生了显着变化,这可能不是你会发现的唯一错误,你会感到非常困惑而不是学习。如果这对您有用,请告诉我。