Php ZF2-控制器中的ServiceManager依赖项
我正在尝试将我的beta DI代码转换为ZF2的发行版。 现在我一开始就陷入了困境,似乎没有任何关于向控制器中注入内容的文档,这让我觉得控制器中存在依赖项是不正常的 现在我只是在做一个Php ZF2-控制器中的ServiceManager依赖项,php,zend-framework2,Php,Zend Framework2,我正在尝试将我的beta DI代码转换为ZF2的发行版。 现在我一开始就陷入了困境,似乎没有任何关于向控制器中注入内容的文档,这让我觉得控制器中存在依赖项是不正常的 现在我只是在做一个var_转储('blah');退出只是尝试运行一些代码。。。 我已经尝试了很多方法,现在我希望这能奏效: module.config.php 'controllers' => array( 'invokables' => array( 'indexController' =>
var_转储('blah');退出代码>只是尝试运行一些代码。。。
我已经尝试了很多方法,现在我希望这能奏效:
module.config.php
'controllers' => array(
'invokables' => array(
'indexController' => 'Application\Controller\IndexController',
)
)
Module.php
public function getControllerConfig() {
return array(
'factories' => array(
'indexController' => function(ControllerManager $cm) {
var_dump('blah');exit;
},
),
);
}
public function onBootstrap(\Zend\EventManager\EventInterface $e)
{
$serviceManager = $e->getApplication()->getServiceManager();
$myDependency = /*something*/;
$controllerLoader = $serviceManager->get('ControllerLoader');
$controllerLoader->addInitializer(function ($controller) use ($myDependency) {
if (method_exists($instance, 'injectMyDependency')) {
$controller->injectMyDependency($myDependency);
}
});
}
现在什么都没有发生,这很令人沮丧。。。我读过一些关于为每个控制器创建工厂的文章,但我有33个,我发现这非常疯狂和愚蠢
我试图注入的是一个用户映射器,用于抓取/保存用户。因此,registerAction使用userMapper在数据库中创建一个用户,当您尝试登录时,它使用userMapper检查是否有用户等。您可以在任何模块中轻松地这样做。php
public function getControllerConfig() {
return array(
'factories' => array(
'indexController' => function(ControllerManager $cm) {
var_dump('blah');exit;
},
),
);
}
public function onBootstrap(\Zend\EventManager\EventInterface $e)
{
$serviceManager = $e->getApplication()->getServiceManager();
$myDependency = /*something*/;
$controllerLoader = $serviceManager->get('ControllerLoader');
$controllerLoader->addInitializer(function ($controller) use ($myDependency) {
if (method_exists($instance, 'injectMyDependency')) {
$controller->injectMyDependency($myDependency);
}
});
}
更简单的方法是让需要依赖项的控制器实现一个接口,并检查控制器是否是该接口的实例,然后进行设置,而不仅仅是检查该方法是否存在……这里的问题是“indexController”被定义为可调用和工厂。我认为它首先检查可调用项,因此当它找到它要查找的内容时,它从不尝试在工厂中运行代码。只需删除“invokables”数组中的条目
我刚刚写了一篇关于这个主题的文章。不必为每个控制器创建单独的工厂类,您可以使用闭包来完成。如果依赖项是可调用的,或者很容易用选项数组配置,那么就更容易了,您所需要的只是一个列出可以注入的类的数组。下面是我的初始值设定项代码,可以插入到任意类中。
刚开始的时候有点棘手-要在实例化时自动注入控制器,您必须在module.config.php的“controllers”部分的“initializer”部分定义initializer-而不是在“service_manager”部分。基本上是为了创建通用的“感知接口”,这将对控制器和其他部分有效-各自的初始值设定项密钥对应同时出现在这两个部分中
// module/SkeletonClassmapGenerator/Item/ImplementedItem/ImplementedItemInitializer.php
namespace SkeletonClassmapGenerator\Item\ImplementedItem;
use Zend\ServiceManager\InitializerInterface;
use SkeletonClassmapGenerator\Provider\GenericInitializerTrait;
class ImplementedItemInitializer implements InitializerInterface
{
static protected $T_NAMESPACE = __NAMESPACE__;
static protected $T_CLASS = __CLASS__;
use GenericInitializerTrait;
}
然后,对于特征(显然在所有初始值设定者之间共享)
}太酷了,这东西似乎有点老套,没有在任何地方提到过。。。我想做的不是一般的做事方式吗?就像使用UserMapper将新用户写入数据库一样$userMapper->register($user);对于此处的instanceAh,它表示在控制器中添加一个方法,以从ServiceManager获取所需的内容,就像userMapper是一个方法一样:getUserMapper(){$sm=$this->getServiceLocator();$this->userMapper=$sm->get('App\Model\userMapper');}之类的东西。正如这里所描述的:它不应该以这种方式(在bootstrap上)。另一点是,ServiceManager
实际上是一个ServiceLocator
或美化的注册表。ZF2也可以避免这种情况。不管怎样,当我有空的时候,如果没有人把答案贴出来,我会回来的=P@Keyne,这就是条令团队建议将entityManager注入控制器的方式…@AndreasLinden无论如何,实际上,您不应该在控制器中使用entityManager,否则它将更像一个服务而不是控制器。控制器是表示层的一部分,如果您遵循良好的实践,那么它不应该与模型层紧密耦合,而是应该有一个服务层,并在那里注入实体管理器。同样地,给定的服务将被注入控制器,并且它将只与它的接口一起工作。您是否找到了一个可接受的答案?我已经用我认为可能的解决方案更新了我的答案。