我试图从另一个模块B调用我的模块A的函数。我通过在模块B的控制器中创建模块A的控制器实例来做到这一点。虽然我可以调用此函数,但它无法访问任何模块。函数get get start at getServiceLocator(),getRequestUri()。 当我尝试跨模块而不是单个模块工作时,所有这些错误都会出现。 我该怎么处理这个?
class IndexController extends AbstractActionController
{
public function indexAction()
{
$sm=($this->getServiceLocator());
$newControl=new ChatController($sm);
$newControl->get_html_code();
}
}
在这里,我将$ sm传递给Controller,因为我无法使用ChatController的getServiceLocator()。同样,我不能使用getRequestUri()。
答案 0 :(得分:1)
Controller 是一个代理,它将请求中的信息委托给模型层。这个(命令或查询)的结果是通过返回给客户端的视图。如果要重用逻辑,则通常在模型层中执行,而不是在控制器中执行。 TL; DR:创建服务层并重用服务中的逻辑,而不是来自控制器。 不自己实例化控制器。
在您的情况下,您可能有一个具有某种逻辑的ChatController
namespace Chat\Controller;
class ChatController
{
public function indexAction()
{
// do something with the request
// you probably have some domain logic here
// return to view here
}
}
对于代码可重用性,最好在域中使用域逻辑。现在最简单的方法是创建一个服务层:
namespace Chat\Service;
class ChatService
{
public function doChat()
{
// place your domain logic here now
}
}
现在,您可以在ChatService上使您的ChatController 依赖。您可以在控制器中注入服务:
use Chat\Service\ChatService;
class ChatController
{
protected $service;
public function __construct(ChatService $service)
{
$this->service = $service;
}
}
现在您只需要在服务管理器中注册聊天服务并为控制器注册工厂。在您的配置中:
'service_manager' => array(
'invokables' => array(
'Chat\Service\ChatService' => 'Chat\Service\ChatService'
),
),
'controllers' => array(
'factories' => array(
'Chat\Controller\ChatController' => 'Chat\Factory\ChatControllerFactory'
),
),
剩下的就是你的控制器工厂:
namespace Chat\Factory;
use Chat\Controller\ChatController;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ChatControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $sl)
{
$sl = $sl->getServiceLocator();
$service = $sl->get('Chat\Service\ChatService');
$controller = new ChatController($service);
return $controller;
}
}
重新使用服务
现在,如果您有一个需要ChatModule逻辑的FooModule,请为该Foo控制器创建一个工厂,注入聊天服务,您就完成了。